使用jest.useFakeTimers()时数据库异步操作导致测试卡住
问题分析与解决方案
你的问题出在Jest默认的legacy fake timers模式上,该模式会干扰异步微任务的正常调度,导致triggerRepository.findOne返回的Promise无法被解析,进而卡在await步骤。
具体修正方案
方案1:切换到Modern Fake Timers模式(推荐)
Jest 27+支持modern模式的fake timers,它不会阻塞微任务队列,能兼容Promise等现代异步操作。修改你的beforeEach代码:
beforeEach(() => { // 使用modern模式替代默认的legacy模式 jest.useFakeTimers('modern'); });
同时移除beforeEach多余的async关键字(jest.useFakeTimers是同步操作,不需要await)。
方案2:手动推进微任务队列(适配legacy模式)
如果必须保留legacy模式,需要手动触发微任务队列来推进Promise的解析:
test('trigger status updates true', async () => { // 先获取Promise实例,再推进微任务 const findOnePromise = triggerRepository.findOne(trigger.id); jest.runAllMicrotasks(); const savedTrigger = await findOnePromise; expect(savedTrigger.status).toBe(TriggerStatus.TRIGGER_STATUS_REGULAR); });
额外注意事项
afterEach中的jest.runOnlyPendingTimers()仅对未执行的定时器有效,如果你的数据库查询不依赖定时器,这步可以保留但不会影响结果;- 确认
triggerRepository.findOne内部没有依赖被fake timers替换的定时器API(如setTimeout),如果有,还需要在合适时机调用jest.runOnlyPendingTimers()推进定时器。
内容的提问来源于stack exchange,提问作者Patricio Stickar
相关产品推荐
相关产品推荐

