使用 Jest 测试 redux 存储

Posted

技术标签:

【中文标题】使用 Jest 测试 redux 存储【英文标题】:Testing the redux store using Jest 【发布时间】:2018-01-04 03:59:02 【问题描述】:

我已经设置了以下函数来配置 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() 返回未定义。我可以从 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 函数在测试环境中表现不同。

【问题讨论】:

这很可能是您的 root reducer 的问题,因为所有操作都经过此操作,包括 redux 实例化时触发的操作。您可以在问题中包含您的减速器代码吗? 在这个阶段,我的根减速器只是简单地返回状态。 const rootReducer = (state, action) => return state; ; 好的,没关系。接下来,你的 thunkMiddleware 函数是什么样的? 我终于有时间重新创建您的测试了。你所拥有的对我来说很好。我用来测试的代码是here。我正在使用 jest@20.0.4。 完全归功于你的伙伴。如果您想快速撰写文章,我很乐意接受您的回答。 【参考方案1】:

所有操作都经过您的:

rootReducer

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

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

正如您found 一样,reducer 的行为不如预期,因为模拟实例没有在测试中保留。

【讨论】:

【参考方案2】:

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

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

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

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

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

【讨论】:

以上是关于使用 Jest 测试 redux 存储的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Jest在ES6类方法中测试对redux存储的调度?

使用 Jest 和 Enzyme 测试使用 Redux 的功能性 React 组件

如何使用 Jest 和 Enzyme 测试具有 Router、Redux 和两个 HOC 的 React 组件?

reactjs - jest 快照测试嵌套的 redux “连接”组件

使用 React、Jest、Redux 和 Thunk 进行无限循环测试

使用 jest 进行 Redux 表单测试