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!
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.
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 .
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.
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.
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);
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
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With