You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jest中伪造timers/promises中的setTimeout定时器?

解决Jest中mock timers/promises setTimeout的问题

因为timers/promises里的setTimeout是不可配置属性,直接用jest.spyOn修改它会触发"Cannot redefine property"错误,而且Jest默认的fake timers不支持Promise版本的定时器,这里给你几个可行方案:

方案1:Mock整个timers/promises模块

直接用jest.mock模拟整个模块,让setTimeout立即返回resolved的Promise,跳过等待:

jest.mock('timers/promises', () => ({
  setTimeout: jest.fn(() => Promise.resolve())
}));

在测试用例中,调用依赖这个方法的代码时,setTimeout会立刻完成,不需要等待实际时间。

方案2:使用Jest现代Fake Timers

Jest 27+版本支持现代fake timers,能处理Promise-based的定时器。你需要启用modern: true配置,然后用异步版本的timer方法快进时间:

  1. 启用现代fake timers:
jest.useFakeTimers({ modern: true });
  1. 在测试中执行完目标代码后,运行所有pending的定时器:
// 执行你的业务代码,比如调用了timersPromises.setTimeout的函数
await yourFunctionThatUsesPromiseTimeout();

// 快进所有定时器,处理完所有Promise
await jest.runAllTimersAsync();

// 然后进行断言
expect(yourMock).toHaveBeenCalled();

方案3:手动封装定时器(推荐长期维护)

在业务代码里封装一层定时器逻辑,比如写一个delay函数:

// utils/delay.js
import { setTimeout as promiseTimeout } from 'timers/promises';

export const delay = (ms) => promiseTimeout(ms);

然后在测试中mock这个封装的函数,这样就不会直接依赖timers/promises,mock起来更灵活:

jest.mock('../utils/delay', () => ({
  delay: jest.fn(() => Promise.resolve())
}));

内容的提问来源于stack exchange,提问作者Michael Goldstein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 09:52:07