Avoiding Mutations
Learn ways to avoid mutations while testing reducers.
One key requirement is that our reducers never modify the state but only create a new one. Our current tests do not verify this behavior.
While we can try to catch these mistakes by manually verifying that the initial state did not change, a simpler approach would be to “freeze” the initial state and have any changes to it automatically stop the tests. To achieve this, we can use the excellent deep-freeze
library, installed as follows:
npm install deep-freeze --save
To use deep-freeze
, we wrap our initial state with a call to deepFreeze()
:
import deepFreeze from 'deep-freeze';
const initialState = deepFreeze(reducer(undefined, { type: 'INIT' }));
Any attempt by any parts of our code to modify initialState
will now automatically throw an error:
initialState.push('test');
> TypeError: Can't add property 0, object is not extensible
To ensure that our reducers never change the original state, we can always call deepFreeze()
on the state before passing it on to the reducer:
// Updated adding to non-empty list test
it('should add recipe to non-empty list', () => {
const initAction = { type: ADD_RECIPE, payload: 'first' };
const baseState = deepFreeze(reducer(initialState, initAction));
expect(reducer(baseState, { type: ADD_RECIPE, payload: 'test' }))
.toMatchSnapshot();
});
Get hands-on with 1400+ tech skills courses.