【问题标题】:How can redux actions be tested?如何测试 redux 操作?
【发布时间】:2020-05-13 05:07:34
【问题描述】:

假设我有一个经典的 redux 结构:动作、组件、容器、reducers。

我在这里使用一个弹出示例

对于行动,我会:

closePopup () {
   return { type: this.actionTypes.CLOSE_POPUP };
}

close () {
   return (dispatch) => {
      dispatch(this.closePopup());
      dispatch(otherAction());
   }
}

组件:

...
<button onClick={this.props.onClose()} />
...

容器:


const mapDispatchToProps = (dispatch) => ({
  onClose () {
    dispatch(popupActions.close());
  },
});

减速器:

case actionTypes.CLOSE_POPUP:
      return {
        ...state,
        isClosed: true,
      };

所以这是一个经典的工作流程。我有一个按钮,它从容器调用一个方法,该方法从 action.js 调用 close() 方法,并调度一些方法,其中一个调度一个改变状态的动作。

我想测试 container.js 中的 onClose 方法是否按照我的预期改变了状态。

例如,它应该是这样的:

describe('close', () => {
  it('should change state', () => {

    // expect(container.onClose()) to change state to { isClosed: true }
  })
})

我怎样才能做到这一点? 这是使用 redux 进行测试的常见模式吗?因为我似乎找不到例子。

【问题讨论】:

  • 不要测试 javascript,也不要测试第三方代码。 测试你的代码。单元是任何软件中最小的可测试部分。单独测试你的 reducer 以断言它们正确更新状态。单独测试您的 UI/props 以断言单击按钮时会调用传递的回调。一旦你开发了一套单元测试,你就可以在经过验证的代码的基础上进行构建,然后转向你所要求的,这更像是一个集成测试,而不是你真正想要在单元测试中做的事情。不过,请查看 react-testing-library,您可能会发现它的测试理念很有用。

标签: reactjs unit-testing redux jestjs


【解决方案1】:

对于close 操作,我只测试它是否调度了其他两个操作——因为这就是它真正所做的一切。正如某人在对您的帖子的评论中所解释的那样,动作创建者的单元测试不应该超越这个函数的实际作用。

如果使用 Jest(或任何测试库)尝试此操作时会遇到问题,如果子操作与 close 编写在同一模块中,则无法轻松模拟它们。

你为什么要嘲笑他们?它们可能更复杂,会自行改变状态,而且还有自己专用的单元测试,所以在这个不相关的测试中调用原始函数并不是一个好主意。

但是有一个巧妙的技巧,您可以在同一模块中导入动作创建器模块,然后使用导入的模块引用来调度其他动作:

import thisModule from './this_action_creator_module';

export const close = () => {
    return (dispatch) => {
        dispatch(thisModule.closePopup());
        dispatch(thisModule.otherAction());
    }
}

以这种方式编写,您可以模拟this_action_creator_module 导出的特定操作。这允许您在测试中调用 close 并断言它调度其他两个操作的模拟(您定义的)。

在我看来,这是单元测试 redux 中最复杂的部分。剩下的就是非常直接的输入-断言-输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2017-05-04
    • 2019-10-31
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多