Vel*_*ack 5 javascript reactjs jestjs react-testing-library
我正在为表单 React 组件编写测试(使用 Jest 和 React 测试库)。我有一个在表单提交上运行的方法:
const onSubmit = (data) => {
// ...
setIsPopupActive(true);
// ...
};
Run Code Online (Sandbox Code Playgroud)
并且useEffect在isPopupActive更改后运行,所以也在提交时:
useEffect(() => {
if (isPopupActive) {
setTimeout(() => {
setIsPopupActive(false);
}, 3000);
}
}, [isPopupActive]);
Run Code Online (Sandbox Code Playgroud)
在测试中,我想检查一下,弹出窗口是否在 3 秒后消失。所以这是我的测试:
it('Closes popup after 3 seconds', async () => {
const nameInput = screen.getByPlaceholderText('Imi?');
const emailInput = screen.getByPlaceholderText('Email');
const messageInput = screen.getByPlaceholderText('Wiadomo??');
const submitButton = screen.getByText('Wy?lij');
jest.useFakeTimers();
fireEvent.change(nameInput, { target: { value: 'Test name' } });
fireEvent.change(emailInput, { target: { value: 'test@test.com' } });
fireEvent.change(messageInput, { target: { value: 'Test message' } });
fireEvent.click(submitButton);
const popup = await waitFor(() =>
screen.getByText(/Wiadomo?? zosta?a wys?ana/)
);
await waitFor(() => {
expect(popup).not.toBeInTheDocument(); // this passes
expect(setTimeout).toHaveBeenCalledTimes(1);
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 3000);
});
});
Run Code Online (Sandbox Code Playgroud)
但是,我收到错误:
expect(received).toHaveBeenCalledTimes(expected)
Matcher error: received value must be a mock or spy function
Received has type: function
Received has value: [Function setTimeout]
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
小智 8
Jest 27对 fakeTimers 进行了重大更改。似乎 Jest 贡献者没有及时更新文档。关于 Github 问题的这条评论证实了这一点。此外,这里相关的公关。
那么,您可以通过两种方式解决您的问题。
module.exports = {
// many of lines omited
timers: 'legacy'
};
Run Code Online (Sandbox Code Playgroud)
jest.useFakeTimers('legacy');
describe('My awesome logic', () => {
// blah blah blah
});
Run Code Online (Sandbox Code Playgroud)
最好使用基于@sinonjs/fake-timers 的新语法。但是我找不到Jest 的工作示例,所以我会尽快更新这个答案。
在你的情况下setTimeout,它不是一个模拟或间谍,而是一个真正的功能。要使其成为间谍,请使用const timeoutSpy = jest.spyOn(window, 'setTimeout'). timeoutSpy并在断言中使用。
您还可以测试不调用该函数的事实setTimeout,而是断言该函数setIsPopupActive被调用一次,并且使用false. 为此,您可能需要执行jest.runOnlyPendingTimers()或jest.runAllTimers()
| 归档时间: |
|
| 查看次数: |
652 次 |
| 最近记录: |