如何在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
相关产品推荐
相关产品推荐

