Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can an ngrx feature selector be unit tested in Jasmine with Angular 6?

I have a feature selector and adjacent selectors for my products feature:

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

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

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

I want to unit test against these selectors. Most articles and posts I read only deal with non-feature selectors, so come time to mock the feature state, my tests are returning undefined for the state object. My spec file looks like this:

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);
});

Error keeps saying Cannot read property 'oldProducts' of undefined, which leads me to believe the getProductState feature selector isn't being mocked properly.

Thanks!

like image 748
J-man Avatar asked Aug 08 '18 20:08

J-man


People also ask

How do you write unit test cases in Angular using jasmine karma?

Create an Angular project with jasmine and karma By doing this, the jasmine and karma configuration is resolved for us. Install and create a new project with angular-cli: Install npm -g @angular/cli. Ng new angular-unit-testing angular unit-testing.

How do I test my NgRx store?

Testing NgRx facade using override/MockStore I recommend you use MockStore (with/without overrideSelector) to mocking the store state. If you want to involve the selectors in the test (integtration testing them), you should use MockStore : You set the state using the setState method from MockStore .

What is NgRx feature selector?

Selectors are pure functions used for obtaining slices of store state. @ngrx/store provides a few helper functions for optimizing this selection. Selectors provide many features when selecting slices of state: Portability. Memoization.

What is Jasmine testing framework and how do you use it for Angular unit testing?

Jasmine is a behavior development testing framework. Unit tests are written using Jasmine and are run to see if individual parts of an application are working correctly. As a result, unit tests will either pass or fail depending on if the code is working correctly or has a bug.


2 Answers

I had the same problem and this thread helped me. Although the solution is not clear.

You need to use the projector function from the selector as @J-man said. For your case would be:

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

like image 186
arturataide Avatar answered Oct 20 '22 06:10

arturataide


Because the feature selector is selecting products from the store state, you'll have to create the global state.

const state = {
  products: {
    name: 'Product1',
    oldProduct: {
      price: 45.00
    },
    newProduct: {
      price: 50.00
    }
  }
}
like image 34
timdeschryver Avatar answered Oct 20 '22 06:10

timdeschryver