Reactjs Jest模拟函数不适用于TohaveEnCalled和mock.calls.length

Reactjs Jest模拟函数不适用于TohaveEnCalled和mock.calls.length,reactjs,unit-testing,jestjs,enzyme,Reactjs,Unit Testing,Jestjs,Enzyme,我正在学习react单元测试,我编写了简单的测试用例,但它不起作用,我在谷歌上搜索了很多地方,我看到的每个地方都是相同的例子,这对我来说都不起作用。我尝试了两种方法来实现call/mock.calls.length 计数器正在增加,我知道我可以检查/测试计数器值以确定按钮是否被单击,但如果没有任何计数器,我只想确保按钮单击触发一个函数,该怎么办 我知道,如果我把这个函数移到其他文件中,然后导入它,那么下面的测试将pas,因为我正在以prop的形式传递这个函数。但是,如果我想测试一个未导入且位于同

我正在学习react单元测试,我编写了简单的测试用例,但它不起作用,我在谷歌上搜索了很多地方,我看到的每个地方都是相同的例子,这对我来说都不起作用。我尝试了两种方法来实现call/mock.calls.length

计数器正在增加,我知道我可以检查/测试计数器值以确定按钮是否被单击,但如果没有任何计数器,我只想确保按钮单击触发一个函数,该怎么办

我知道,如果我把这个函数移到其他文件中,然后导入它,那么下面的测试将pas,因为我正在以prop的形式传递这个函数。但是,如果我想测试一个未导入且位于同一文件中的函数,该怎么办

从“React”导入React;
导入“/Login.css”;
类登录扩展了React.Component{
状态={
柜台:0
};
多洛金=(事件)=>{
设{counter}=this.state;
this.setState((prevstate)=>({counter:prevstate.counter+1}));
//log(“处理登录按钮点击”);
};
render(){
const{counter}=this.state;
返回(
登录
{计数器}
);
}
}
导出默认登录;
测试用例

it("Handle login button click", () => {
  const mockOnClick = jest.fn();

  const wrapper = shallow(<Login onClick={mockOnClick} />);
  wrapper.find("button").simulate("click");
  wrapper.find("button").simulate("click");
  // mockOnClick();
  console.log(wrapper.state("counter"));
  // expect(mockOnClick).toHaveBeenCalled();
  expect(mockOnClick.mock.calls.length).toEqual(2);
});
it(“处理登录按钮点击”,()=>{
const mockOnClick=jest.fn();
常量包装器=浅();
包装器。查找(“按钮”)。模拟(“单击”);
包装器。查找(“按钮”)。模拟(“单击”);
//mockOnClick();
console.log(wrapper.state(“计数器”));
//expect(mockOnClick).tohavebeincall();
expect(mockOnClick.mock.calls.length).toEqual(2);
});

因为
onClick
事件在
按钮上,而不是在
登录组件上,所以函数没有按您期望的方式绑定。实际上,您需要做的是模拟组件,然后用伪造的函数替换该函数

it(“处理登录按钮点击”,()=>{
const mockOnClick=jest.fn();
const wrapper=shallow();
wrapper.instance().doLogin=mockOnClick;
//必须强制更新,否则第一个.simulate调用将触发实际函数。
wrapper.instance().forceUpdate();
包装器。查找(“按钮”)。模拟(“单击”);
包装器。查找(“按钮”)。模拟(“单击”);
//mockOnClick();
console.log(wrapper.state(“计数器”));
//expect(mockOnClick).tohavebeincall();
expect(mockOnClick.mock.calls.length).toEqual(2);

});与其在沙箱中发布完整应用程序演示的链接,不如将相关的代码和测试粘贴到您的评论中?好的,请稍等。通常人们喜欢演示,所以我这样做了,但让我同时发布两个。@petarkolaric:完成!这里的问题是
Login
组件没有
onClick
事件,内部的按钮有。您没有实际绑定到正确的元素,因此从来没有实际调用您的模拟函数。如果模拟被触发,计数器将不会增加,因为模拟被触发而不是实际函数。谢谢!“这不是一个真正有用的应用程序功能测试”,你的意思是我也应该测试/验证该功能引起的反应,而不仅仅是测试它是否被调用?比如,如果该函数触发了一些axios请求,那么我也应该用moxios测试它,或者如果它改变了状态,那么我应该测试状态变量的变化?比如
expect(wrapper.state(“counter”)).toEqual(2)
correct。您总是希望测试组件的结果,而不是尽可能地激活它们。
it("Handle login button click", () => {
  const mockOnClick = jest.fn();

  const wrapper = shallow(<Login onClick={mockOnClick} />);
  wrapper.find("button").simulate("click");
  wrapper.find("button").simulate("click");
  // mockOnClick();
  console.log(wrapper.state("counter"));
  // expect(mockOnClick).toHaveBeenCalled();
  expect(mockOnClick.mock.calls.length).toEqual(2);
});