【问题标题】:Mock function is not called in click event while testing with jest and enzyme使用 jest 和酶进行测试时,在单击事件中不调用模拟函数
【发布时间】:2019-09-27 13:15:55
【问题描述】:

我正在尝试测试一个 redux 连接的反应组件,即 Cart,但我无法让下面的测试工作。我想看看是否在按钮的单击处理程序中调用了一个动作(从 material-ui 包导入)。

动作通过 mapDispatchToProps 映射到道具。

const mapDispatchToProps = dispatch =>
  bindActionCreators(SelectItemGalleryActions, dispatch);

我也在用

import configureStore from 'redux-mock-store';

在测试中将模拟存储传递给我的组件。

处理程序被调用,但间谍没有记录它已被调用。我已经尝试了在这里或 github 上找到的大多数解决方案(浅层、模拟、潜水、使用 jest.fn() 而不是 spy() ...);你有什么想法?我假设调用了对我尝试测试的模拟函数的不同引用。

首先我要传递一个模拟商店和一个动作

const props = {
  store: mockStore({ selectItemGallery: { cartItems: [{ name: 'one' }] } }),
  removeAllItemsFromCartAction: spy()
};
const wrapper = mount(<Cart {...props} />);

之后我搜索我的按钮并模拟点击它

const button = wrapper.find(Button).at(0);
button.prop('onClick')('test1');
button.prop('onClick')('test2');

当我运行测试时,点击会起作用。我从处理程序内部获得 console.log() 输出。

期望

expect(props.removeAllItemsFromCartAction.called).toBe(true);

但是它没有被调用。

这是实际的处理程序

 <Button
    color="primary"
    onClick={x => {
      console.log(`onClick called on component with info ${x}`);
      removeAllItemsFromCartAction();
      console.log('removeAllItemsFromCartAction call is above me');
    }}>    
        {t('Clear All')}
 </Button>

控制台显示

欢迎任何提示或想法。谢谢。

版本:

"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"jest": "^23.6.0",
"sinon": "^7.2.2",
"react": "^16.8.2"

【问题讨论】:

  • 试试 button.simulate("click")
  • 谢谢,已经试过了,但结果还是一样。
  • 你能补充一下你是如何设置你的 spy() 的吗?通常它比这更复杂。您需要定义一个可以引用的变量。例如 const myMock = jest.fn() 并将该变量传递给您的道具。
  • 已经尝试过 jest.fn(); spy() 函数来自 import { spy } from 'sinon';应该同样工作,但我猜有相同的额外录制功能。

标签: reactjs redux jestjs enzyme sinon


【解决方案1】:

这似乎不是测试动作是否通过mapDispatchToProps 映射到道具的正确方法 被调用了。

实际调用了来自模拟存储的调度,我们只需要验证它是否发送了正确的操作 (https://redux.js.org/recipes/writing-tests)。

正确的测试是:

  it('Should call the removeAllItemsFromCartAction', () => {
    const props = {
      store: mockStore({ selectItemGallery: { cartItems: [{ name: 'one' }] } })
    };
    const wrapper = mount(<Cart {...props} />);
    const button = wrapper.find(Button).at(0);
    button.prop('onClick')();
    console.log(props.store.getActions());
    expect(props.store.getActions()).toEqual([
      { type: 'REMOVE_ALL_ITEMS_FROM_CART' }
    ]);
  });

【讨论】:

    【解决方案2】:

    这些测试可能非常挑剔,但我怀疑问题在于您如何设置间谍,因为根据您的控制台日志,该功能正在受到打击。首先,我认为您实际上并不需要间谍,您可以使用传入的模拟函数,只要 removeAllItemsFromCartAction() 实际上在您的组件道具上。

    const myMock = jest.fn();
    const props = {
      store: mockStore({ selectItemGallery: { cartItems: [{ name: 'one' }] } }),
      removeAllItemsFromCartAction: myMock
    };
    const wrapper = mount(<Cart {...props} />);
    const button = wrapper.find(Button).at(0);
    button.simulate("click");
    expect(myMock).toHaveBeenCalled();
    

    你可能已经尝试过了,但这是我唯一的想法。

    【讨论】:

    • 另外,我想看看这种方法是否也适用于浅层而不是安装,只需调用 .instance() 并在您的实例上进行查找。
    • 是的 :( 已经尝试过了。但它应该像你说的那样工作,如果不是可能与我的环境或错误包有关。你能告诉我什么版本的酶,你在开玩笑吗使用?
    猜你喜欢
    • 2018-04-05
    • 2018-03-25
    • 2016-09-21
    • 2019-12-22
    • 2019-09-01
    • 2020-12-31
    • 2018-10-24
    • 1970-01-01
    • 2018-09-28
    相关资源
    最近更新 更多