reactjs - Jest 酶模拟函数不适用于 toHaveBeenCalled 和 mock.calls.length
问题描述
我正在学习反应单元测试,我写了简单的测试用例,但它不起作用,我用谷歌搜索了很多,到处都看到相同的例子,这对我不起作用。我尝试了两种方式来HaveBeenCalled/mock.calls.length。
计数器正在增加,我知道我可以检查/测试计数器值以确定是否单击了按钮,但是如果没有任何计数器并且我只想确保按钮单击触发功能怎么办?
我知道如果我将此函数移动到其他文件然后将其导入,那么下面的测试将通过,因为我将该函数作为道具传递。但是,如果我想测试一个未导入且在同一个文件中的函数怎么办?
import React from "react";
import "./Login.css";
class Login extends React.Component {
state = {
counter: 0
};
doLogin = (event) => {
let { counter } = this.state;
this.setState((prevstate) => ({ counter: prevstate.counter + 1 }));
// console.log("Handle login button click");
};
render() {
const { counter } = this.state;
return (
<table width="100%" border="0" cellPadding={4}>
<tr>
<td>
<input type="text" name="username" placeholder="Username" />
</td>
</tr>
<tr>
<td>
<input type="password" name="password" placeholder="Password" />
</td>
</tr>
<tr>
<td>
<button onClick={this.doLogin}>LogIn</button>
{counter}
</td>
</tr>
</table>
);
}
}
export default Login;
测试用例
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);
});
解决方案
因为onClick
事件是在组件上button
而不是在Login
组件上,所以函数没有按照您期望的方式绑定。您实际上要做的是模拟组件,然后用伪造的函数替换该函数。
it("Handle login button click", () => {
const mockOnClick = jest.fn();
const wrapper = shallow( < Login / > );
wrapper.instance().doLogin = mockOnClick;
//MUST forceUpdate or the first .simulate call will trigger the real function.
wrapper.instance().forceUpdate();
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);
});
https://codesandbox.io/s/amazing-easley-hd0hc
请注意,instance
必须forceUpdate
避免调用真正的函数。此外,这是用假函数替换函数而不是调用真实函数,因此只是测试onClick
机制本身,这并不是对应用程序功能的真正有用测试。
推荐阅读
- ignite - Ignite 中的简单选择查询缺少行
- angularjs - AngularJS:ui-select接受字符串而不是数组
- python - “命令不同步;您现在无法运行此命令”在 django 模型上运行分页器时
- javascript - 函数的返回值无法正常工作。如何为函数 checkIfExist() 设置正确的返回值?
- linux-kernel - 如何仅在 linux 中的 udp 数据包上生成网络损伤
- amazon-web-services - AWS Cognito 验证码长度更改
- javascript - 为什么这个递归 javascript 函数表达式返回未定义?
- json - 如何从 SQL Server 中的动态节点加载 OPENJSON
- spring-boot - Spring Boot 的 keycloak 启动器在哪里?
- python - 取决于计算 groupby 对象中两个列单元格之间的差异的列