Friday, December 18, 2020

Angular: Mock NgRedux for Unit Testing

If you use Redux in your Angular web application (likely it is an NgRedux from Angular Redux) and develop unit tests for components that depend on the Redux store sometimes it's easier to mock the Redux store rather than deal with incorrect values that it may supply in a test scenario. If this sounds like your situation, read on.

If one searches the Internet for how to mock NgRedux they will find a number of suggestions and examples including the testing code in the NgRedux Git repository itself. Most of the suggestions I've found seem too elaborate and unnecessary to my  taste considering that I don't want to spend any efforts on creating a mock NgRedux store class nor testing NgRedux related functionality. If you are in a similar mindset below is how I mocked the NgRedux an easy way.

The Problem

There are components in an Angular application that depend on an application state that is implemented as an NgRedux store as NgRedux<IAppState>>. The components receive a reference to the NgRedux store via Angular dependency injection in a constructor similar to:

constructor(ngRedux: NgRedux<IAppState>, ...)

When writing unit tests for the components with NgRedux dependency using Jasmin framework it is likely that the application state will not be initialized correctly in a unit testing environment and the component logic may fail because of an unexpected application state.

The Solution

The easiest solution that I've found and works for me is mocking an NgRedux using Jasmin Spy when initializing a TestBed for a unit test. To do so two questions need to be answered: what dependency type will be provided and what methods need to be mocked. The answers are below:

providers: [
    	provide: NgRedux,
        useValue: jasmine.createSpyObj<NgRedux<IAppState>>(
        	['dispatch', 'configureStore', 'select'])

The type and the value are self-explanatory based on what dependency is being injected into a component's constructor and the methods listed will most likely be used. Of course, based on a specific testing scenario, the select method can be mocked to provide a concrete value as well.


If more elaborate testing scenarios are required such as testing the select values or actions of the NgRedux store there is a MockNgRedux class that is a part of the NgRedux package and included in the NgReduxTestingModule module. Read more about using the MockNgRedux here https://github.com/angular-redux/store/blob/master/articles/intro-tutorial.md#unit-testing-selections.

No comments:

Post a Comment