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

Jest升级至v28后多测试用例触发done多次调用错误求助

解决Jest v28多测试用例使用done回调时报错的问题

问题背景

将Jest从v24升级到v28,配置了jsdom测试环境,设置了setupFiles指向setup.js:

"jest": { "testEnvironment": "jsdom", "setupFiles": ["<rootDir>/setup.js"] }

当同一测试文件中多个使用done回调的测试用例一起运行时,出现错误:

Expected done to be called once, but it was called multiple times.
单独运行单个测试用例时无异常。

可能原因及解决方案

1. 全局副作用未清理(setup.js或测试全局操作)

Jest v28对测试环境的隔离机制比v24更严格,但如果setup.js中存在全局事件监听、定时器或未清理的异步操作,会跨测试用例残留,导致done被意外多次调用。

  • 检查setup.js,比如是否添加了window.addEventListener这类全局监听,必须在afterEach中移除对应的监听:
    // setup.js
    let handleResize;
    beforeEach(() => {
      handleResize = () => { /* 业务逻辑 */ };
      window.addEventListener('resize', handleResize);
    });
    afterEach(() => {
      window.removeEventListener('resize', handleResize);
      jest.clearAllTimers();
      jest.resetAllMocks();
    });
    
  • 确保所有全局异步操作(如定时器、Promise)在每个测试用例结束后被清理。

2. 测试用例内部异步逻辑重复触发done

如果测试用例中绑定了事件监听但未在测试结束后解绑,当后续测试用例触发相同事件时,会再次调用之前测试的done回调:

// 错误示例:未解绑事件
it('test resize', (done) => {
  window.addEventListener('resize', () => {
    expect(true).toBe(true);
    done();
  });
  window.dispatchEvent(new Event('resize'));
});

// 修复:测试后解绑事件
it('test resize', (done) => {
  const handler = () => {
    expect(true).toBe(true);
    done();
  };
  window.addEventListener('resize', handler);
  window.dispatchEvent(new Event('resize'));
  afterEach(() => {
    window.removeEventListener('resize', handler);
  });
});

3. 改用async/await替代done回调

Jest v28更推荐使用async/await处理异步逻辑,避免done回调带来的多次调用风险,代码更简洁易维护:

// 替代done的写法
it('test async logic', async () => {
  const result = await someAsyncFunction();
  expect(result).toBe('expected');
});

4. 检查测试环境版本兼容性

确认jest-environment-jsdom的版本与Jest v28匹配,避免版本不兼容导致的环境异常:

npm list jest-environment-jsdom

确保版本为28.x.x,若不一致则重新安装对应版本:

npm install jest-environment-jsdom@28 --save-dev

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:06:27