Chai模拟API响应测试时报错Function is not stubbed如何修复?
错误原因
你当前模拟的res.status是普通自定义函数,不是Sinon生成的存根(stub),Sinon的断言方法只能识别自身创建的存根实例,因此执行sinon.assert.calledOnce(res.status)时抛出对应错误。
修复方案
这里提供两种可选修复方式:
方案1:删除冗余的Sinon断言(最简修复)
你已经在自定义的status、send方法内部写了参数校验逻辑,只要函数执行过程中触发了res.status(401).send()调用,内部的断言就会自动校验参数是否符合预期,不需要额外加Sinon的调用次数断言。
修改后的测试代码如下:
it('should fail when missing auth header', async () => { const req = {} as functions.https.Request; const res: any = { status: function (statusCode: number) { assert.strictEqual(statusCode, 401); return this; }, send: function (body: unknown) { assert.deepEqual(body, { error: "Unauthorized", }); }, }; await createNudgeBankLinkingNotifications(req, res); });
注意:这种方案如果代码逻辑异常没有走到res.status调用分支,测试会直接通过,不会捕获问题,适合临时快速验证。
方案2:使用Sinon存根模拟res对象(更严谨的测试写法)
用Sinon创建status、send存根,既可以校验调用参数,也能验证调用次数,避免漏测分支问题,代码如下:
it('should fail when missing auth header', async () => { const req = {} as functions.https.Request; // 用sinon创建存根 const sendStub = sinon.stub(); const statusStub = sinon.stub().returnsThis(); // 返回this模拟链式调用 const res: any = { status: statusStub, send: sendStub }; await createNudgeBankLinkingNotifications(req, res); // 统一校验调用情况 sinon.assert.calledOnceWithExactly(statusStub, 401); sinon.assert.calledOnceWithExactly(sendStub, { error: "Unauthorized" }); });
这种写法更符合单元测试的惯例,逻辑更清晰,后续如果要扩展测试场景也更易维护。
额外优化建议
你当前模拟的req对象是空值,如果hasAuthHeaderAPIKey方法有其他req属性校验逻辑,建议按需补充对应属性的模拟值,避免测试结果不符合预期。
内容的提问来源于stack exchange,提问作者rafaelpolonio
相关产品推荐
相关产品推荐

