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

为何mocha-chai测试用done()仍超时?含20秒setTimeout场景

解决Mocha测试中setTimeout导致的超时问题

嘿,这个问题我之前也碰到过!核心原因很简单:Mocha的默认测试超时时间只有2000ms(2秒),但你在测试里加了20秒的延迟,远远超过了这个上限——所以哪怕你最后会调用done(),Mocha在2秒后就已经判定测试超时失败了,根本等不到你的延迟结束。

下面给你几个具体的解决方案,按推荐程度排序:

1. 给单个测试用例设置超时(最推荐)

针对需要延迟的那个it测试,单独设置更长的超时时间。注意要使用普通函数作为it的回调,不能用箭头函数(否则this无法指向Mocha的测试上下文):

it('执行带20秒延迟的POST请求', function(done) {
  // 把超时时间设为25000ms(25秒),比你的20秒延迟多留一点缓冲
  this.timeout(25000);

  // 前面的测试逻辑...

  setTimeout(() => {
    // 最后一次POST调用
    post('/your-endpoint', yourData, (err, response) => {
      if (err) {
        // 错误分支也要调用done,把错误传进去
        return done(err);
      }
      // 这里加你的断言逻辑,比如检查response状态码、返回值等
      assert.strictEqual(response.statusCode, 200);
      // 所有逻辑完成后调用done
      done();
    });
  }, 20000);
});

2. 给整个describe块设置超时

如果这个describe里的多个测试都需要较长时间,可以统一在describe里设置超时:

describe('我的测试套件', function() {
  // 整个块下的所有测试都用25秒超时
  this.timeout(25000);

  it('第一个测试', function(done) {
    // ...测试逻辑
    done();
  });

  it('带20秒延迟的测试', function(done) {
    setTimeout(() => {
      post('/your-endpoint', yourData, (err, response) => {
        // 处理和断言
        done();
      });
    }, 20000);
  });
});

3. 全局设置超时(不推荐,除非必要)

如果你的所有测试都需要更长时间,也可以在运行Mocha时通过命令行参数设置:

mocha --timeout 25000

或者在mocha.config.js配置文件里添加全局超时:

module.exports = {
  timeout: 25000
};

额外注意事项

  • 务必确保done()在所有代码分支都被调用(包括错误分支),避免出现测试挂起的情况。
  • 如果你用Promise代替回调,同样需要设置超时时间,并且要确保返回Promise,比如:
it('用Promise实现延迟POST', function() {
  this.timeout(25000);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      post('/your-endpoint', yourData)
        .then(response => {
          assert.strictEqual(response.statusCode, 200);
          resolve();
        })
        .catch(err => reject(err));
    }, 20000);
  });
});

内容的提问来源于stack exchange,提问作者A.G.Progm.Enthusiast

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:57:35