NgRx MockStore
WARNING: This is a Google translated (originally Chinese) and reposted article that probably is mostly comfortably understandable for senior JavaScript developers.
This time I would like to write about MockStore recently added as a new feature of NgRx.
What is MockStore
MockStore is a module to make it easy to test with Component using Store.
It was merged into master at the end of October and it was scheduled to be released at v 7.0.0.
I have not written any document yet and it is not mentioned in ngrx.io , but the function itself is stable.
Because it is very convenient, those who use v7 (beta) should start using this article by referring to this article.
Unfortunately v7 is not released as stable yet (2018 - 12 - 18), so if you are using the 6 system you need to wait a bit more.
Purpose of MockStore
MockStore is designed to make it simple to write tests of Component using Store.
In NgRx, Component only performs select / dispatch on Store, so you do not need to know the implementation of Store or Reducer. These are completely loosely coupled relationships. However, when actually writing tests, you need to set up Store and Reducer as well as do normal module settings. In other words, in order to write a Component test, you need to understand the relationship between Store and Reducer and set them individually. This is an unnecessary work and it's just a hassle.
If you use MockStore, you can use Store without setting these settings.
As an example, let's compare the test settings of Component when not using MockStore.
Test setting of Component not using MockStore
Testbed . ConfigureTestingModule ({
imports : [
StoreModule . ForRoot ({
users : CombineReducers ( UserReducers ),
}),
],
})
In preparation for testing Component, it is necessary to set StoreModule and related Reducer settings.
Test setting of Component using MockStore
Testbed . ConfigureTestingModule ({
providers : ProvideMockStore (),
});
Only this. Store and Reducer settings are lost, which makes it very simple.
How to use MockStore
Let's actually look at how to use MockStore.
Since it is basically just a module to set State, there are only two functions, initial value setting and value change.
Setting Import
MockStore is @ngrx/store/testingnow available from the module. If you are using v7 you can use it immediately without installing it anymore.
import { MockStore , provideMockStore } from '@ ngrx / store / testing' ;
Setting the initial value of State
MockStore is the earlier provideMockStoreyou can pass the State to be the initial value. If not specified is undefinedused as the initial value.
interface MockStoreConfig < T > {
initialState ?: T ;
}
function provideMockStore < T = any > ( config : MockStoreConfig < T > = {}): Provider [];
Actually it can be used as follows.
The describe ( 'setting of the initial value of State' , () => {
the let MockStore : MockStore < any > ;
const initialState = {
users : [{ id : 1 , name : 'user1' }, { id : 2 , name : 'user 2' }],
};
beforeEach (() => {
TestBed . configureTestingModule ({
providers : provideMockStore ({ initialState }),
});
mockStore = TestBed . get ( Store );
});
it ( 'initial value of the Store is set in initialState' , ( done The : any ) => {
MockStore . subscribe ( val => {
the expect ( val .) ToEqual ( initialState );
done The ();
});
} );
});
In this article we will skip the sample code for Component's test, but store.select()if you are doing it in OnInit it is a good idea to use this initial setting.
Change the value of State
Since MockStore does not use Reducer, the way to update the value of State changes. If you want to change the value MockStore.setStateof State, set the State manually at an arbitrary timing by using a method called dispatch instead of dispatching Action .
export class MockStore < T > the extends Store < T > {
setState ( NextState : T ): void ;
}
Actually it can be used as follows.
describe ( 'Change the value of State' , () => {
let mockStore : MockStore < any > ;
beforeEach (() => {
TestBed . configureTestingModule ({
providers : provideMockStore (),
});
mockStore = TestBed . get ( Store );
});
It ( 'The value of the State can be changed at any time using the SetState' , ( Done : Any ) => {
Const newState = {
Users : [{ Id : 3 , Name : 'User3' }, { Id : 4 , name : 'user 4 ' }],
};
MockStore . SetState ( newState );
mockStore . subscribe ( val => {
expect ( val ). toEqual ( newState );
done ();
});
});
});
It can be used quite intuitively.
I think that it will become possible to write well with good outlook, such as when testing the Component for each State state.
in conclusion
This is the function of MockStore.
In this article, as an introduction to the overview, I think that you can actually write a test of Component in another article.
As an aside, there provideMockStoreare functions like Effects also exist in provideMockActionsEffects, you can easily write tests of Effects by using the function.
I think NgRx is a very good library personally, as it is designed to be very easy to write tests. MockStore, please use it from now on.