使用Jest测试redux商店

时间:2017-07-28 07:31:30

标签: javascript unit-testing redux jestjs redux-thunk

我已设置以下功能来配置Redux商店

const configureStore = (initialState) => {
  console.log(initialState);
  const store = createStore(
    rootReducer,
    initialState,
    applyMiddleware(
      thunkMiddleware
    )
  );

  console.log(store.getState());
  return store;
};

现在,从我的正常应用程序入口点运行此操作,控制台日志显示,例如:

-> Initial state = { Test: "test" }
-> (Store gets created)
-> Store state = { Test: "test" }

这很好,正如预期的那样。然后,我尝试使用以下Jest测试确认此行为

it("should set the supplied initial state", () => {
    const initialState = {
      TestState: "Test"
    };

    const store = configureStore(initialState);
    expect(store.getState()).toEqual({
      TestState: "Test"
    });
  });

此测试失败,因为store.getState()返回undefined。我可以从configureStore函数中看到控制台日志,并显示:

-> Initial state = { Test: "test" }
-> (Store gets created)
-> Store state = undefined

为什么行为不同?是Jest嘲笑createStore函数吗?我已经读过Jest不再自动模仿依赖项了,为什么会出现这种情况呢?我是Jest单元测试的新手,因此我们将非常感谢能解决这个问题的任何亮点。

编辑:我确实意识到我基本上只是测试一个Redux函数,这可能是非常不必要的。无论如何,我想了解导致此问题的测试行为。

第二次编辑:按如下方式编写自己的createStore函数会使测试通过:

const createStore = (reducer, initState, middleware) => {
  return {
    getState: () => (initState)
  };
};

但是这仍然没有解释为什么redux createStore函数在测试环境中表现不同。

2 个答案:

答案 0 :(得分:0)

感谢Ben Smith,我已经明白了。

当我自己运行测试时,它通过了。问题是我之前有过这个测试:

it("should set the root reducer", () => {
    rootReducer.default = jest.fn();
    const store = configureStore();
    store.dispatch({
      type: "TestAction"
    });
    expect(rootReducer.default).toHaveBeenCalled();
  });

我在嘲笑减速器,出于某种原因,我认为减速器不会在两次测试中保持嘲讽,但显然它确实如此。为了解决它,我只是在模拟它之前存储了unmocked reducer,然后将这个清理添加到模拟reducer函数的测试的末尾:

//Cleanup - unmock reducer
rootReducer.default = actualReducer;

答案 1 :(得分:0)

所有操作都通过您的:

rootReducer

包括Redux实例化时触发的操作,例如初始操作的类型为' @@ redux / INIT'。

因此,如果您遇到意外状态,请始终检查您的减速器是否按预期运行。

当你found时,reducer的行为不符合预期,因为模拟实例没有在测试中保留。