Recently I have been refactoring state shape in a fairly large redux application, and I have found that one of the obstacles to doing to is that the tests for my reducers clearly have a lot of "knowledge" about the "shape" of the state tree.
There are lots of tests that look like this:
const nextState = reduce(startState, action.doSomething());
expect(nextState.foo.bar.somethingwasdone).toBeTruthy();
etc.
So now, when I want to restructure so that the somethingwasdone
boolean is stored under state.foo.baz.somethingwasdone
, I have to make similar changes in a potentially quite large number of tests.
One thing I have been wondering is: does it make sense to decouple reducer tests from state shape by using selectors? So:
const nextState = reduce(startState, action.doSomething());
expect(selectors.wasSomethingDone(nextState)).toBeTruthy();
The benefit of this is that, when you change your state shape, you just have to change the relevant selectors to match, and you potentially don't have to change your reducer tests at all.
One downside is that, when a reducer test fails, you don't know a priori if that's because there's a problem with the reducer, or a problem with a selector. But this doesn't seem like that much of a costly disadvantage compared to the advantages.
One thing that gives me pause is that I never see this pattern in redux tutorials, books, or documentation.
Am I missing something? Are there other disadvantages that I haven't thought of? Is the problem I mention above more serious that I thought?
Any advice or feedback would be very welcome.