0

I recently started using Immer in redux reducers in my react app since I have a lot of nested states in them. (lets avoid the fact the these nesting can be solved with sub reducers).

The usage of Immer is clear for me, but once I started to write unit tests with jest I started wondering, that should I avoid using Immer in the tests?

Lets have a basic reducer example:

export default function (state = initialState, action) {
    return produce(state, (draftState) => {
        switch (action.type) {
            case MY_TYPE:
                draftState.some.nested.flag = true;
                break;
        }
    });
}

then my test which also using Immer

it('should handle MY_TYPE', () => {
    const storeState = reducer(initialState, {
        type: MY_TYPE
    });
    const newState = produce(initialState, (draftState) => {
        draftState.some.nested.flag = true;
    });
    expect(storeState).toEqual(newState);
});

So my question is that should I avoid using Immer produce in the tests and make the copy of the nested object manually with the spread syntax ? Something like:

.toEqual({
    ...initialState,
    some: {
        ...initialState.some,
        nested: {
            ...initialState.some.nested,
            flag: true
        }
    }
})

So is there any pitfalls using Immer in tests ?

Zoltán Jére
  • 604
  • 5
  • 15

1 Answers1

0

In this case Immer does not change all the state. For example:

const state = {
  some: {
    another: {},
    nested: {
      flag: true
    }
  }
};

const nextState1 = produce(state, draft => {
  draft.some.nested.flag = false;
});

const nextState2 = produce(state, draft => {
  draft.some.nested.flag = false;
});

expect(nextState1).toEqual(nextState2);

expect(nextState1.another).toBe(nextState2.another); // true!
expect(nextState1).toBe(nextState2); // false
expect(nextState1.some).toBe(nextState2.some); // false
expect(nextState1.some.nested).toBe(nextState2.some.nested); // false

Where "toBe" is a function which check identity of object instances (unlike "toEqual"). I think, you should not avoid using Immer in the unit tests. Probably it requires another assert function which checks that only part of tree is changed.

anton62k
  • 371
  • 1
  • 6