Search code examples
typescriptunit-testingreduxjestjsreducers

Why is my reducer still setting the state with invalid input in my test case?


I have a reducer that sets the redux state with only numerical values, however, when I try to test it with bad input, it seems that the reducer still changes the state to the bad input. Why is my reducer still updating the state when I give it non numerical inputs?

This is what my action looks like:

  setCount: (count: number) => createAction(ActionTypes.SET_COUNT, {count})

This is the relevant code from my reducer:

case ActionTypes.SET_COUNT: {
  draft.count = action.payload.count;
  break;
}

And this is my unit test:

 describe(`(Action) ${ActionTypes.SET_COUNT}`, () => {
    const unsuccessfulAction = Actions.setCount("bad input");

    it("Should not update the state for the count when input is not a number", () => {
      const state = myReducer(undefined, unsuccessfulAction);
      expect(state.count).toBe(null); 
    });
  });

When I run my test case, the received result is "bad input" and the expected result is null.


Solution

  • With this information from your question:

    I have a reducer that sets the redux state with only numerical values

    case ActionTypes.SET_COUNT: {
      draft.count = action.payload.count;
      break;
    }
    

    There is no logic here that supports that it sets the state "with only numerical values". The code you've shown indiscriminately sets whatever is in the 'count' property of your payload to the 'count' property of your state.

    If you actually want to restrict to numerical values, you need to actually include code in the reducer that only changes draft.count when action.payload.count is numerical

    e.g.

    case ActionTypes.SET_COUNT: {
      if (isNumeric(action.payload.count)) {
        draft.count = action.payload.count;
      }
      break;
    }
    

    It is up to you to find an appropriate implementation of isNumeric.