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

尝试抛出错误时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工具:

  1. 先安装依赖:
npm install sinon --save-dev
  1. 编写测试:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:29:57