我正在写一个单元测试,它测试一个在继续之前等待超时的函数,我试过使用
jest.useFakeTimers();
jest.advanceTimersByTime(20000);
但我一直收到错误信息: Timeout - Async callback was not invoked within the 20000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
模块文件:
async function main()
{
const promisesArray: Promise<void>[] = [];
// lots of logic and async calls //
for (const userRecord of records) {
promisesArray.push(verifyUserRecord(userRecord.userId));
}
await Promise.all(promisesArray);
}
function waitTimeout(ms: number) {
return new Promise((resolve) => setTimeout(() => resolve(true), ms));
}
async function verifyUserRecord(userId) {
await waitTimeout(CHECK_EXECUTION_STATUS_TIMEOUT);
await <some other method call>
/////////////// more logic /////////////
}
测试文件
describe('main test', () => {
beforeAll(() => {
// calls to jest spy on //
});
beforeEach(() => {
jest.useFakeTimers();
// various mocks //
});
afterEach(() => {
jest.resetAllMocks();
});
afterAll(() => {
jest.useRealTimers();
jest.restoreAllMocks();
});
it('Should successfully run', async () => {
const p = main();
jest.advanceTimersByTime(60000);
jest.runAllTimers(); // <- explicitly tell jest to run all setTimeout, setInterval
jest.runAllTicks(); // <- explicitly tell jest to run all Promise callback
await p;
// validations //
});
});
但是当我从测试文件调用main方法时,我得到了上面的错误。当调试时,我看到它到达waitTimeout
,然后等待或移动到测试模块中的下一个it
。它没有模拟超时,并继续模块文件逻辑。
如何正确测试文件并模拟超时?
先谢了。
3条答案
按热度按时间ozxc1zmp1#
模拟计时器时使用了错误的API
jest.setTimeout(20000);
用于设置jest等待测试完成的最大超时。如果测试时间过长,jest将抛出错误回到您的问题,因为您使用
jest.useFakeTimers();
,所以必须显式地告诉jest用尽所有宏任务(setTimeout)和微任务(Promise回调)。我对你的代码做了一点修改,这样expect就可以工作了
输出:
lhcgjxsq2#
您可以使用
runOnlyPendingTimers
,这将刷新所有挂起的计时器。用途
8yparm6h3#
另一种模拟setTimeout的方法: