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

如何在Chai中获取不符合预期消息的错误的原始堆栈跟踪?

解决Chai+Mocha测试中错误不匹配时显示原始堆栈跟踪的问题

我用Chai搭配Mocha做测试,测试代码如下:

expect(() => f(a, b)).to.throw('Sriharikota we have a problem.')

需求是:当抛出的错误消息与指定内容不匹配时,能显示原始错误的完整堆栈跟踪。比如实际错误消息是'Houston we have a problem.'时,需要拿到包含被测代码调用栈的信息,方便排查测试在非预期位置失败的问题。

尝试过设置chai.config.includeStack = true,但只得到Chai内部及测试模块的调用栈,完全没有被测代码的信息:

at Proxy.assertThrows (node_modules/chai/lib/chai/core/assertions.js:2730:16)
      at Proxy.methodWrapper (node_modules/chai/lib/chai/utils/addMethod.js:57:25)
      at Context.<anonymous> (/path/to/my/code/test/mytest.ts:31:53)
      at process.processImmediate (node:internal/timers:478:21)

可行解决方案

Chai的throw断言在失败时,默认会封装原始错误,导致堆栈丢失。要获取被测代码的原始堆栈,需要手动捕获错误后再做断言:

方法1:手动捕获错误并验证

// 先执行被测函数,捕获原始错误
let thrownError;
try {
  f(a, b);
} catch (err) {
  thrownError = err;
}

// 先断言错误存在
expect(thrownError).to.be.an('error');
// 验证错误消息
expect(thrownError.message).to.equal('Sriharikota we have a problem.');

当消息不匹配时,Mocha会抛出断言失败的错误,你也可以在catch块里主动打印原始错误堆栈:

// 可选:主动打印原始堆栈
if (thrownError && thrownError.message !== 'Sriharikota we have a problem.') {
  console.error('\n原始错误堆栈:\n', thrownError.stack);
}

方法2:自定义Chai断言(进阶)

如果需要频繁使用,可以封装一个自定义断言,自动保留原始错误堆栈:

chai.Assertion.addMethod('throwWithStack', function(expectedMsg) {
  const fn = this._obj;
  let error;
  try {
    fn();
  } catch (err) {
    error = err;
  }

  this.assert(
    error instanceof Error,
    'expected function to throw an error',
    'expected function not to throw an error'
  );

  this.assert(
    error.message === expectedMsg,
    `expected error message to be "${expectedMsg}", got "${error.message}"\n原始堆栈:\n${error.stack}`,
    `expected error message not to be "${expectedMsg}"`
  );
});

// 使用方式
expect(() => f(a, b)).to.throwWithStack('Sriharikota we have a problem.');

这样当消息不匹配时,断言失败信息会直接包含原始错误的堆栈。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:53:26