尝试抛出错误时Mocha单元测试无法通过求助
问题分析
你的verify中间件是异步函数,且外层包含完整的try/catch逻辑:所有内部抛出的错误都会被捕获,然后调用next(err),并不会让async函数返回rejected的Promise。同时,同步的to.throw()断言只能捕获函数执行时立即抛出的同步错误,完全无法识别这种异步逻辑里的错误传递,这就是测试失败的核心原因。
正确的测试思路应该是:模拟next函数,验证当没有Authorization头时,next被调用且传入了符合预期的错误对象。
解决方案
方式一:手动模拟next函数
无需额外依赖,直接跟踪next的调用参数:
const { verify } = require('../path/to/your/middleware'); it('Should call next with 401 error if no auth header provided.', async function () { const req = { get: () => null, }; let receivedError = null; const next = (err) => { receivedError = err; }; // 执行异步中间件 await verify(req, {}, next); // 断言错误属性 expect(receivedError).to.be.an.instanceOf(Error); expect(receivedError.message).to.equal('Not Authenticated'); expect(receivedError.statusCode).to.equal(401); });
方式二:使用Sinon(更专业的函数模拟)
如果需要更灵活的函数调用跟踪,可使用Sinon工具:
- 先安装依赖:
npm install sinon --save-dev
- 编写测试:
const sinon = require('sinon'); const { verify } = require('../path/to/your/middleware'); it('Should call next with 401 error if no auth header provided.', async function () { const req = { get: sinon.stub().returns(null), }; const next = sinon.stub(); await verify(req, {}, next); // 断言next被调用一次,且参数符合预期 sinon.assert.calledOnce(next); const err = next.firstCall.args[0]; expect(err).to.be.an.instanceOf(Error); expect(err.message).to.equal('Not Authenticated'); expect(err.statusCode).to.equal(401); });
补充说明
- 若你的中间件没有外层try/catch,async函数会把内部抛出的错误包装成rejected Promise,此时可结合
chai-as-promised插件断言Promise的reject状态,但当前代码结构下,这种方式不适用。 - 异步测试必须通过
async/await或done回调通知Mocha测试完成,否则会出现超时或断言无效的问题。
内容的提问来源于stack exchange,提问作者Christopher
相关产品推荐
相关产品推荐

