为何Jest异步测试在legacy假计时器下正常,modern假计时器却失效?
为何Jest的legacy假计时器正常运行,modern假计时器却失效?
以下测试使用Jest的legacy假计时器能正常通过,但切换到默认的modern假计时器就会出现问题:
jest.useFakeTimers({ legacyFakeTimers: true }); // 正常运行 // jest.useFakeTimers(); // 无法运行 it('simpleTimer', async () => { async function simpleTimer(callback) { await callback(); setTimeout(() => { simpleTimer(callback); }, 1000); } const callback = jest.fn(); await simpleTimer(callback); for (let i = 0; i < 8; i++) { jest.advanceTimersByTime(1000); await Promise.resolve(); // 允许PromiseJobs队列中的待处理任务执行 } expect(callback).toHaveBeenCalledTimes(9); // 测试通过 });
该测试示例来自Stack Overflow,我已尝试原帖中几乎所有解决方案,也参考过讨论Jest假计时器与Promise兼容的相关帖子。
使用modern假计时器时,终端会一直阻塞,必须输入^C才能终止。我还尝试过以下几种处理Promise队列的方法:
// 1 const flushPromises = () => new Promise(setImmediate); // 2 const timeout = (ms) => // 用于类似`await timeout(1000)`的等待 new Promise(resolve => { setTimeout(resolve, ms) }); // 3 await new Promise(process.nextTick);
目前已经找不到新的搜索方向,我的环境版本:
- Node.JS: v18.15.0
- Jest: v29.5.0
原本我的setup文件中仅包含jest.useFakeTimers(),后来发现setup文件和测试文件中都调用了该方法,于是移除了setup文件中的调用,只保留一处。之后收到新的报错:
thrown: "Exceeded timeout of 5000 ms for a test.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See Jest docs for test timeout."
但切换回jest.useFakeTimers({ legacyFakeTimers: true })后,测试又恢复正常。
内容的提问来源于stack exchange,提问作者Rick Stanley
相关产品推荐
相关产品推荐

