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

非async API中使用sinon.stub进行Mocha测试超时问题求助

解决回调式API的Mocha测试超时问题

问题核心在于你对sqlSelect的stub方式错误:原函数是基于回调的异步函数,但你用了returns()直接返回数据,这不会触发后续的回调逻辑,导致API里的adminfunctions.getAllCurrency的回调从未执行,响应一直没发送,测试自然超时。

不需要修改API的回调写法,只要修正测试里的stub逻辑即可,有两种常用方案:

方案1:使用sinon.stub().callsFake()手动触发回调

直接模拟sqlSelect的行为,调用传入的回调函数并传递测试数据:

it("getallcurrency api = success 200", (done) => {
  const getUserByIdStub = sinon
    .stub(dbutil, "sqlSelect")
    .callsFake((sqlText, callback) => {
      // 手动触发回调,传入模拟的成功数据
      callback({ id: 1, name: "Test User", email: "test@example.com" });
    });

  chai
    .request(appInstance)
    .get("/allcurrency/1")
    .end((err, res) => {
      expect(res).to.have.status(200);
      expect(res.body).to.deep.equal({ id: 1, name: "Test User", email: "test@example.com" });
      getUserByIdStub.restore();
      done();
    });
});

方案2:使用sinon.stub().yields()快速触发回调

Sinon提供了yields()方法,专门用于模拟接受最后一个参数为回调的函数,自动把参数传递给回调:

it("getallcurrency api = success 200", (done) => {
  const getUserByIdStub = sinon
    .stub(dbutil, "sqlSelect")
    .yields({ id: 1, name: "Test User", email: "test@example.com" });

  chai
    .request(appInstance)
    .get("/allcurrency/1")
    .end((err, res) => {
      expect(res).to.have.status(200);
      expect(res.body).to.deep.equal({ id: 1, name: "Test User", email: "test@example.com" });
      getUserByIdStub.restore();
      done();
    });
});

为什么之前的写法不行?

原sqlSelect的逻辑是:接受SQL文本和一个回调函数,内部异步执行数据库操作后调用这个回调返回结果。你的测试用returns()直接返回数据,但这个返回值不会被原函数的调用者(adminfunctions.getAllCurrency)使用,因为它只关心传入的回调是否被触发。所以只要让stub正确触发回调,整个链条就会正常执行,API会发送响应,测试也不会超时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:26:17