测试一个有 Promise 和 setTimeout 的函数,为什么会超时?
Testing a function which has a Promise and setTimeout, why is it timing out?
我正在尝试测试一个在 promise 中包含 setTimeout
的函数。但是它总是超时。
这是函数:
export const sleep = async (duration: number): Promise<void> => {
await new Promise<void>((resolve) => {
setTimeout(resolve, duration);
});
if (process.env.NODE_ENV === "test") {
console.log("sleep end");
}
};
这是我的测试:
import { sleep } from "../../helpers/utils";
console.log = jest.fn();
jest.useFakeTimers();
test("calls sleep with correct argument and calls console.log", async () => {
const NODE_ENV = "test";
const SLEEP_DURATION = "100";
process.env = { ...process.env, NODE_ENV, SLEEP_DURATION };
const timeoutSpy = jest.spyOn(global, "setTimeout");
await sleep(+SLEEP_DURATION);
jest.runAllTimers();
expect(sleep).toHaveBeenCalledWith(+SLEEP_DURATION);
expect(timeoutSpy).toHaveBeenCalledWith(+SLEEP_DURATION);
expect(console.log).toHaveBeenCalledWith("sleep end");
});
问题是,当我尝试 运行 时,测试失败并显示此消息:
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
我试过 jest.setTimeout(10000)
只是抛出 Exceeded timeout of 10000ms ...
的错误
知道为什么会这样吗?或者如何解决?
谢谢!
这是一个更接近您想要的解决方案。重要的是,您不能 await
使用虚假计时器解决承诺,否则它永远不会解决。相反,您可以调用将 sleep
函数的 return 值分配给变量,然后 运行 计时器,然后等待变量。
我还调整了超时侦测器的 expect
语句,因为它需要两个参数。最后,我删除了您对 sleep
被调用持续时间的期望,因为您实际上是在测试中这样做,所以做出这样的断言似乎不值得。
console.log = jest.fn();
jest.useFakeTimers();
test("calls sleep with correct argument and calls console.log", async () => {
const NODE_ENV = "test";
const SLEEP_DURATION = "100";
process.env = { ...process.env, NODE_ENV, SLEEP_DURATION };
const timeoutSpy = jest.spyOn(global, "setTimeout");
const sleepFn = sleep(+SLEEP_DURATION);
jest.runAllTimers();
// Now that we ran timers we can await the promise resolving
await sleepFn;
// timeout takes two arguments
expect(timeoutSpy).toHaveBeenCalledWith(
expect.any(Function),
+SLEEP_DURATION
);
expect(console.log).toHaveBeenCalledWith("sleep end");
});
我正在尝试测试一个在 promise 中包含 setTimeout
的函数。但是它总是超时。
这是函数:
export const sleep = async (duration: number): Promise<void> => {
await new Promise<void>((resolve) => {
setTimeout(resolve, duration);
});
if (process.env.NODE_ENV === "test") {
console.log("sleep end");
}
};
这是我的测试:
import { sleep } from "../../helpers/utils";
console.log = jest.fn();
jest.useFakeTimers();
test("calls sleep with correct argument and calls console.log", async () => {
const NODE_ENV = "test";
const SLEEP_DURATION = "100";
process.env = { ...process.env, NODE_ENV, SLEEP_DURATION };
const timeoutSpy = jest.spyOn(global, "setTimeout");
await sleep(+SLEEP_DURATION);
jest.runAllTimers();
expect(sleep).toHaveBeenCalledWith(+SLEEP_DURATION);
expect(timeoutSpy).toHaveBeenCalledWith(+SLEEP_DURATION);
expect(console.log).toHaveBeenCalledWith("sleep end");
});
问题是,当我尝试 运行 时,测试失败并显示此消息:
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
我试过 jest.setTimeout(10000)
只是抛出 Exceeded timeout of 10000ms ...
知道为什么会这样吗?或者如何解决?
谢谢!
这是一个更接近您想要的解决方案。重要的是,您不能 await
使用虚假计时器解决承诺,否则它永远不会解决。相反,您可以调用将 sleep
函数的 return 值分配给变量,然后 运行 计时器,然后等待变量。
我还调整了超时侦测器的 expect
语句,因为它需要两个参数。最后,我删除了您对 sleep
被调用持续时间的期望,因为您实际上是在测试中这样做,所以做出这样的断言似乎不值得。
console.log = jest.fn();
jest.useFakeTimers();
test("calls sleep with correct argument and calls console.log", async () => {
const NODE_ENV = "test";
const SLEEP_DURATION = "100";
process.env = { ...process.env, NODE_ENV, SLEEP_DURATION };
const timeoutSpy = jest.spyOn(global, "setTimeout");
const sleepFn = sleep(+SLEEP_DURATION);
jest.runAllTimers();
// Now that we ran timers we can await the promise resolving
await sleepFn;
// timeout takes two arguments
expect(timeoutSpy).toHaveBeenCalledWith(
expect.any(Function),
+SLEEP_DURATION
);
expect(console.log).toHaveBeenCalledWith("sleep end");
});