【问题标题】:mock click event and use toBeCalled() got error of not a function error模拟点击事件并使用 toBeCalled() 得到不是函数错误的错误
【发布时间】:2019-05-14 12:53:24
【问题描述】:

这是我尝试测试按钮的点击事件

it('should call addItem when button is clicked', () => {
    const addItem = jest.fn()
    const button = mount(<App onClick={addItem} />)
    //button.find('button').props.onClick()
    //expect(addItem).toBeCalled()
  })

这是 DOM

<div className="App">
        <input type="text" onChange={this.changeInput} />
        <button onClick={this.addItem}>Add</button>
      </div>

错在哪里?

【问题讨论】:

  • 尝试使用button.find('button').simulate('click')。此外,您可能希望将其从 button 重命名为更合适的名称,例如 wrappercomponent
  • @AnaLizaPandac 差不多了,但仍然无法断言 codesandbox.io/s/mk6r923r8

标签: javascript ecmascript-6 jestjs enzyme


【解决方案1】:

测试什么:

检查addItem 函数是否在单击add 按钮时被调用。

为什么测试失败:

你模拟了错误的函数addItem 是在您的类中定义的 instance 函数,但您正在测试的是您作为 prop 传递给组件的函数。

如何测试组件中定义的函数/方法:

要么你想观察一个方法被调用,但保留原来的实现,要么模拟实现,但在测试运行后恢复原来的,那么你可以使用jest.spyOn这两者中的任何一个。

如果您只想“监视”对 addItem 函数的调用,但保留原始实现,那么您可以这样做。

it("should call addItem when button is clicked", () => {
  const spy = jest.spyOn(App.prototype, "addItem");
  const wrapper = shallow(<App />);
  wrapper.find("button").simulate("click");

  expect(spy).toHaveBeenCalled();
  // don't forget to clear the spy
  spy.mockClear();
});

如果你真的想模拟这个函数,然后恢复原来的实现然后你可以这样做。

it("should call addItem when button is clicked", () => {
    const mocked = jest.spyOn(App.prototype, "addItem");
    // override the implementation
    mocked.mockImplementation(() => "mock");
    const wrapper = shallow(<App />);

    wrapper.find("button").simulate("click");
    expect(mocked).toHaveBeenCalled();

    mocked.mockRestore();
  });

查看工作实现:https://codesandbox.io/s/mm06k8px4y

请注意,在代码中,我更改了 addItem 实现通过手动绑定到类而不是使用箭头函数(类属性),因为我们需要该函数位于类原型中以便于测试。否则,将导致此错误:Cannot read property '_isMockFunction' of undefined,因为它不存在于类原型中。

此外,“类属性”仍处于试验阶段,不是 ES6 的一部分。

更多详情请参阅:https://github.com/facebook/react/issues/9851

【讨论】:

  • 奇怪,为什么我以前没有看到这种实现?你能指导我正确的前端单元测试路径吗?
  • 我会尽力帮助您解决问题。也有很多关于这个主题的在线资源,所以进一步阅读会有所帮助。至少,就我而言,并像现在一样练习。
  • 几个问题:i) 所以你不使用箭头函数并使用 bind(this) 进行测试? ii)您将不得不编写该代码块来测试每个事件?例如。 onChange,onClick,这是很多工作..
猜你喜欢
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-30
  • 2016-03-27
相关资源
最近更新 更多