代码之家  ›  专栏  ›  技术社区  ›  J-man

如何使用Angular6在Jasmine中对NGRX功能选择器进行单元测试?

  •  3
  • J-man  · 技术社区  · 6 年前

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

    const getProductState = createFeatureSelector<fromProducts.State>('products');
    
    export const getOldProducts = createSelector(
        getProductState,
        state => state.oldProducts
    );
    
    export getNewProducts = createSelector(
        getProductState,
        state => state.newProducts
    );
    

    我想对这些选择器进行单元测试。我读的大多数文章和文章只处理非特征选择器,所以来模拟特性状态,我的测试返回。 undefined 对于state对象。我的规范文件如下所示:

    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 功能选择器未正确模拟。

    谢谢!

    1 回复  |  直到 6 年前
        1
  •  1
  •   timdeschryver    6 年前

    因为功能选择器正在选择 products 在store状态中,必须创建全局状态。

    const state = {
      products: {
        name: 'Product1',
        oldProduct: {
          price: 45.00
        },
        newProduct: {
          price: 50.00
        }
      }
    }
    
        2
  •  0
  •   arturataide    5 年前

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

    你需要使用 projector 正如@j-man所说的那样,从选择器中调用函数。 你的情况是:

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