reactjs - Not getting expected result from .toHaveBeenCalledTimes() in react-testing-library
问题描述
Anyhow, trying to test if a function has been called after its fired. The fireEvent
is working as I get a console.log
from that function. But the .toHaveBeenCalledTimes(1)
returns 0. What have i missed?
If I have the handleLoginSubmit
function in the parent and pass it as a prop down to the child and in the test everything passes. But if it's in the same component it fails. Using typescript if that has any meaning.
This is tested
import React, { FC } from 'react';
type Event = React.FormEvent<HTMLFormElement>;
interface Login {
handleLoginSubmit?: (event: Event) => React.ReactNode;
}
const Login: FC<Login> = () => {
const handleLoginSubmit = (_event: Event) => {
console.log('Firing' ); // This is logged
};
return (
<form data-testid='form' onSubmit={(event) => handleLoginSubmit(event)}>
<input data-testid='email'/>
<input data-testid='password'/>
<button data-testid='login-button'>login</button>
</form>
);
};
export default Login;
My test for submiting
it('should handle ClickEvents', () => {
const handleLoginSubmit = jest.fn();
const { getByTestId } = render(<Login/>);
expect(getByTestId('login-button')).toBeTruthy();
fireEvent.submit(getByTestId('form'));
expect(handleLoginSubmit).toHaveBeenCalledTimes(1);
});
Error message
● Login page › should handle ClickEvents
expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
32 | fireEvent.submit(getByTestId('form'));
33 |
> 34 | expect(handleLoginSubmit).toHaveBeenCalledTimes(1);
| ^
35 |
36 | });
37 | });
at Object.it (__tests__/components/Login.test.tsx:34:31)
解决方案
您不能断言是否handleLoginSubmit
要直接调用该函数。Login
因为它是在SFC的私有范围内定义的。您无法模拟或监视此功能,因为您无法访问它。因此,您需要间接测试它。由于您console.log
在此功能中使用,我们可以窥探console.log
. 如果它已被调用,则表示该handleLoginSubmit
函数已被调用。
例如
index.tsx
:
import React, { FC } from "react";
type Event = React.FormEvent<HTMLFormElement>;
interface Login {
handleLoginSubmit?: (event: Event) => React.ReactNode;
}
const Login: FC<Login> = () => {
const handleLoginSubmit = (_event: Event) => {
console.log("Firing");
};
return (
<form data-testid="form" onSubmit={event => handleLoginSubmit(event)}>
<input data-testid="email" />
<input data-testid="password" />
<button data-testid="login-button">login</button>
</form>
);
};
export default Login;
index.spec.tsx
:
import { render, fireEvent } from "@testing-library/react";
import Login from "./";
import React from "react";
it("should handle ClickEvents", () => {
const logSpy = jest.spyOn(console, "log");
const { getByTestId } = render(<Login />);
expect(getByTestId("login-button")).toBeTruthy();
fireEvent.submit(getByTestId("form"));
expect(logSpy).toHaveBeenCalledTimes(1);
});
覆盖率 100% 的单元测试结果:
PASS src/stackoverflow/59162138/index.spec.tsx
✓ should handle ClickEvents (42ms)
console.log node_modules/jest-mock/build/index.js:860
Firing
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.987s, estimated 9s
源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59162138
推荐阅读
- python - 为什么 Spacy 的 NER 训练器返回令牌而不返回实体?
- r - 如何获得第一个和最后一个时间顺序之间的差异?
- angular - 如何允许某些带有角度的 URL 并从中收集数据
- javascript - html/javascript 中的画布线模糊
- swift - 如何在 Swift 中将此日期字符串格式“2018-03-30T14:36:10.093”格式化为日期
- html - 如何结合活动按钮和悬停?
- image - 如何在 Flutter/Dart 中将资产图像转换为位图?
- javascript - 按数组元素数组过滤数组?
- amazon-web-services - AWS Lambda w/ SQS 触发器,SQS Lambda 目标,从不添加到目标队列
- java - 如何检查在editText中插入的文本是否存在于SQLite数据库中,如果存在则返回一条消息,如果不存在则返回不同的消息