如何测试redux动作?

问题描述 投票:0回答:1

假设我有一个经典的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());
  },
});

reducer:

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

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

我想测试一下 onClose 方法改变了我所期望的状态。

作为一个例子,它应该是这样的。

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

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

我如何才能做到这一点呢? 这是用redux测试的常见模式吗? 因为我似乎找不到例子。

reactjs unit-testing redux jest
1个回答
0
投票

对于 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 中,并断言它派发了其他两个动作的 mocks(你定义的)。

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

© www.soinside.com 2019 - 2024. All rights reserved.