如何在Angular 6的Jasmine中对ngrx功能选择器进行单元测试?

时间:2018-08-08 20:03:51

标签: angular unit-testing jasmine angular6 ngrx

我有一个功能选择器和我的产品功能的相邻选择器:

const getProductState = createFeatureSelector<fromProducts.State>('products');

export const getOldProducts = createSelector(
    getProductState,
    state => state.oldProducts
);

export getNewProducts = createSelector(
    getProductState,
    state => state.newProducts
);

我想针对这些选择器进行单元测试。我只阅读的大多数文章和帖子都涉及非功能选择器,所以现在该来模拟功能状态了,我的测试返回了状态对象的undefined。我的规格文件如下所示:

beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [
            StoreModule.forRoot({}),
            StoreModule.forFeature('products', fromProduct.reducer)
        ],
        declarations: [],
        providers: [{
            provide: Store, useClass: class { select = jasmine.createSpy('select'); dispatch = jasmine.createSpy('dispatch'); }
        }]
    })
    mockStore = TestBed.get(Store);
}));

it('getOldProducts should return the oldProducts', () => {
    const state = {
        name: 'Product1',
        oldProduct: {
            price: 45.00
        },
        newProduct: {
            price: 50.00
        }
    }: fromProduct.State;
    expect(selectors.getOldProducts(state.oldProducts)).toBe(state.oldProducts);
});

错误总是说Cannot read property 'oldProducts' of undefined,这使我相信getProductState功能选择器没有被正确模拟。

谢谢!

2 个答案:

答案 0 :(得分:1)

由于功能选择器正在从商店状态中选择products,因此您必须创建全局状态。

const state = {
  products: {
    name: 'Product1',
    oldProduct: {
      price: 45.00
    },
    newProduct: {
      price: 50.00
    }
  }
}

答案 1 :(得分:0)

我遇到了同样的问题,这个线程帮助了我。尽管解决方案尚不清楚。

您需要使用@ J-man所说的选择器中的projector函数。 对于您的情况是:

expect(selectors.getOldProducts.projector(state.oldProducts)).toBe(state.oldProducts);