This content originally appeared on Level Up Coding - Medium and was authored by Dennis
NgRx is a framework for angular that helps to separate the backend logic from the frontend, making the code easier cleaner. To know more about how it works and how to use it, do check out my previous article — NgRx explained. Testing with NgRx is pretty straightforward, you’ll just need to use the mocks provided.
Firstly, as the store is injected in the constructors, and since unit tests are supposed to be isolated, therefore we’ll need to add the provideMockStore() into the providers array when we configure the testing module. Then we can create a reference to our store, declaring as type MockStore<AppState>, and get its value injected from the TestBed.
To stub the values from the selectors, we can use the overrideSelector(<Selector>, <Value>) method and fixture.detectChanges() to refresh the data.
store.overrideSelector(Selector.books, sampleBooks);
fixture.detectChanges()
If we need to reuse the overridden selector, we can assign it to a variable like let showDetailSelector = store.overrideSelector(Selector.showDetail, true);. We can update the values by using the setResult(<Value>) method. But we’ll need to call store.refreshState() after that to refresh the store.
showDetailSelector.setResult(false);
store.refreshState();
fixture.detectChanges();
A sample of how all these can be done are available on https://github.com/thecodinganalyst/bookstore/blob/master/src/app/app.component.spec.ts.
Testing Selectors
Supposing we have a selector as such
const books = createSelector( bookStore, (bookStoreState => bookStoreState.books));
To test our selectors, we can use the projector(<State>) method of our selector to get the expected value.
it('should get the books', () => {
const result = Selector.books.projector(initialState.bookStore);
expect(result.length).toBe(5);
});
A full example is on https://github.com/thecodinganalyst/bookstore/blob/master/src/app/state/books.selectors.spec.ts.
Testing Reducers
As reducers are simply pure functions to get a new state from a current state with a specific action, we just need to stub our state and create an action object to pass to our reducer.
Supposing we have an action as such
const booksLoaded = createAction("[BookList] Books Loaded", props<{ books: ReadonlyArray<Book> }>())
We can directly reference the booksLoaded action and pass in the books parameter - const action = BookStoreActions.booksLoaded({books: [sampleBook]});. Then we can pipe it to our reducer by - const state = booksReducer(initialState, action);, and do assertions directly on the state object.
A full example is on https://github.com/thecodinganalyst/bookstore/blob/master/src/app/state/books.reducer.spec.ts.
Testing Effects
We’ll need to add the effects as it is, and action and store as mocks.
For an action — loadBooks, a side effect of the action is to call the service to load the books from the database. And after the books are loaded, another action - booksLoaded is triggered with the books as a payload.
To test the above effect,
- first we put a spy on the service to return a mock list of books, so that the workings of the service do not interfere with our unit test.
- Then we trigger the action — actions$ = of(BookStoreActions.loadBooks);.
- Then we subscribe to the effect, and put our assertions
A full example is available on https://github.com/thecodinganalyst/bookstore/blob/master/src/app/state/books.effects.spec.ts.
This article is originally published on https://thecodinganalyst.github.io/knowledgebase/how-to-test-ngrx/
How to test NgRx was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Dennis
Dennis | Sciencx (2022-06-17T14:57:33+00:00) How to test NgRx. Retrieved from https://www.scien.cx/2022/06/17/how-to-test-ngrx/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.