非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
相关产品推荐
相关产品推荐

