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

使用Chai测试Express异步路由失败问题求助

解决Chai+Mocha测试Express异步路由超时问题

我仔细看了你的测试代码、路由逻辑和报错信息,发现两个核心问题导致了测试超时,咱们一步步来解决:

问题根源分析

1. 路由代码里的低级拼写错误

你的路由里有个笔误:res.sendStatu(400)(少了最后一个s),正确的Express响应方法是res.sendStatus()。这个错误会直接同步抛出异常,但这个异常不在user.login_user()的Promise链范围内,所以不会被你写的.catch(err => { ... })捕获。Express会把这个异常传给默认错误处理中间件,但这个过程会导致请求没有正常返回响应,测试里的Chai请求一直挂着等结果,最终触发超时。

2. 测试代码混用Promise与done()

你在测试里同时用了Promise的.then()/.catch()和Mocha的done()回调,而且在catch里直接throw err——这会导致如果请求出错,错误没有被Mocha捕获,也不会调用done(),Mocha就会一直等待直到超时。另外,你的测试断言也写错了:根据路由逻辑,空请求体应该返回400,而不是200,这也会导致测试失败。

解决方案

第一步:修复路由代码的拼写错误

把所有的res.sendStatu()改成res.sendStatus(),同时推荐用async/await的try/catch替代Promise链,代码更简洁易读:

router.post('/', async function(req, res, next) {
  try {
    if (!req.body) return res.sendStatus(400);
    if (!req.body.usr) return res.sendStatus(400);
    if (!req.body.psw) return res.sendStatus(400);

    let user = new _USER();
    const ret = await user.login_user(req.body.usr, req.body.psw);
    
    if (ret === false) {
      return res.sendStatus(401);
    }
    req.session.active = true;
    req.session.user = ret;
    res.sendStatus(200);
  } catch (err) {
    _UTILS.errorHandler(err, false, true);
    res.sendStatus(500);
  }
});

第二步:修正测试代码的写法

不要混用done()和Promise,优先直接返回Promise(Mocha会自动处理Promise的resolve/reject),同时修正断言的状态码:

describe('/Login wrong user', () => {
  it('It should return 400 when login POST has no data', () => {
    // 直接返回Promise,Mocha会自动等待它完成
    return chai.request(app)
      .post('/login')
      .send({})
      .then((res) => {
        expect(res).to.have.status(400);
      });
  });
});

如果一定要用done()写法,记得在catch里把错误传给done():

describe('/Login wrong user', () => {
  it('It should return 400 when login POST has no data', (done) => {
    chai.request(app)
      .post('/login')
      .send({})
      .then((res) => {
        expect(res).to.have.status(400);
        done();
      })
      .catch((err) => {
        done(err); // 把错误传递给Mocha处理
      });
  });
});

额外小提示

  • 测试前确保Express的全局错误处理中间件配置正确,避免未捕获的异常导致请求挂起;
  • 异步测试优先用返回Promise的写法,代码更简洁,不容易踩回调陷阱;
  • 写路由时注意方法名拼写,这类低级错误很容易引发奇怪的超时/无响应问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:20:42