下面是一个我想测试的自定义钩子:
import { useEffect, useState } from "react";
export const useAlert = () => {
const [alert, setAlert] = useState(null);
useEffect(() => {
let timerId = setTimeout(() => {
console.log("Timeout, removing alert from DOM");
setAlert(null);
}, 200);
return () => clearTimeout(timerId);
}, [alert]);
return {
renderAlert: alert ? alert : null,
setAlert,
};
};
字符串
它只允许组件设置警报,并在300毫秒后自动清除警报。
这是对上述挂钩的工作测试
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { useAlert } from "../components/useAlert";
// jest.useFakeTimers();
function FakeComponent() {
const { renderAlert, setAlert } = useAlert();
return (
<div>
<button onClick={() => setAlert("fake alert")}>Set Alert</button>
<p>{renderAlert}</p>
</div>
);
}
test("testing", async () => {
const user = userEvent.setup();
render(<FakeComponent />);
const button = screen.getByRole("button", { name: /set alert/i });
await user.click(button);
expect(screen.getByText(/fake alert/i)).toBeInTheDocument();
await waitFor(() => {
expect(screen.queryByText(/fake alert/i)).not.toBeInTheDocument();
});
});
型
我的疑问是,我想在测试中使用jest的假计时器,但如果我取消注解jest.useFakeTimers()
行,测试就会中断,说测试超时,因为默认的超时值是5000 ms。
我不明白为什么会这样,请帮帮忙!
3条答案
按热度按时间eivgtgni1#
要在
@testing-library/user-event
的最新版本中使用假计时器,您需要在设置userEvent
时配置advanceTimers
选项(文档):字符串
以下是您的更新测试:
型
hec6srdp2#
可以将
delay
属性作为null
传递给userEvent.setup
调用字符串
oyt4ldly3#
@som-shekhar-mukherjee的解决方案是好的,但不严格,尽管它设法为这个非常特殊的情况下工作。
但是,我建议在
userEvent
的advanceTimers
配置中使用advanceTimersToNextTimer
而不是runOnlyPendingTimers
。这样做可以确保jest只运行
userEvent
的内部方法设置的计时器。如果userEvent
触发了代码中使用计时器的内容,runOnlyPendingTimers
将耗尽这些内容。advanceTimersToNextTimer
只会提前userEvent
所导致的计时器。基本上,您的
setTimeout
回调需要在测试中运行两次。useEffect
)。"fake alert"
后至少200 ms。@som-shekhar-mukherjee提出的解决方案之所以有效,是因为一旦测试到达并执行
await user.click(button);
行,runOnlyPendingTimers
将耗尽所有挂起的计时器:useEffect
设置的定时器;user.click
调用设置的计时器。它恰好适用于您的情况,但却阻止您控制正在测试的计时器何时发生。(你可能不知道)提前了你的测试组件的计时器。这是不正确的,因为,在真实的的执行中,它不会只在单击按钮时被耗尽。这个
所以我建议如下:
字符串
总而言之,在
userEvent
配置上使用advanceTimersToNextTimer
解决了阻塞问题,并允许您在测试期间更正确地控制所测试组件的计时器发生的情况。测试挂钩是由React Testing Library docs建议的。顺便说一句,我使用您的组件和上面的挂钩仔细测试了我提出的解决方案。如果您对我的答案有疑问,请告诉我。