Mock your NGRX store, the easy way!

NGRX, is an amazing way to apply the redux pattern in Angular.Writing tests for this pattern within our Angular applications is also a part of our daily development work. When writing unit tests we want to test small pieces of logic, that way it’s easy to identify bugs in an early stage.

But there is a small (big) problem! As of ngrx version 6 `store.select` is deprecated, the new way is to use `store.pipe(select….`

NGRX 6: store.select is deprecated

So we need to find a way to mock the select so that we are able to provide it in a proper way to our test component. We only want to test the component and not the functionality behind it, after all we are writing UNIT test, This means we just want to test a particular part of the functionality, not the complete project! This allows us to test a small part, so we can discover fast how to solve these problems.

For the demo application we create a random quote display.

Display the quote on the screen

We want to test the QuoteComponent to check if everything is displayed correctly on the screen. Below is an example of how we would write a unit testwhen we would use this.store.select

But this no longer a valid approach since we need to do it like this this.store.pipe(select(...))

A solution is needed !!!

We will mock the complete store, since we want decide ourselves what’s in the store.

If we want to use the ngrx store we need a few key concepts:

Actions describe unique events that are dispatched from components and services.

State changes are handled by pure functions called reducers that take the current state and the latest action to compute a new state.

Selectors are pure functions used to select, derive and compose pieces of state.

State accessed with the Store, an observable of state and an observer of actions.

Step 1: Create a mockActions

As we want to mock our complete store, we want to have a mock action to fill the store with data!

Step 2: Create a mockReducer

From the moment the store retrieves a mocked action, it will be saved to the store. In fact we will store every action.

No complex logic is added, as we want to decide in our test how the data looks. Don’t forget we only want to test a small piece of our code!

Step 3: Create a MockStoreModule

Of course we want to use the reducer for the right feature. And we want to avoid to much boilerplate code! So let’s create a shared module!

We want to achieve something like

With the forRoot method we can decide which feature we want to mock in our store. Also the initial state we can decide ourselves!

Let’s take a look at the MockStoreModule:

the forRoot(featureName: string, initialState: unknown) is required to make the featureName and initial value of the state! This function will call a factory method before the test will start, which will initialise the mock reducer as described above. ReduceManager is provided by default by @ngrx/store. The reduce manager provide some methods to add and remove features dynamically. It is also used internal in the ngrx store.