如何使用Sinon存根对象参数中的onReceipt回调函数?
问题原因及解决办法
你当前写法的核心问题是匹配逻辑错误:在withArgs里用{onReceipt: sinon.stub().yields()},是在要求传入的options对象的onReceipt属性必须是你这里新建的这个特定stub实例。但实际业务代码里传入的onReceipt是你封装Promise时定义的回调函数,和这个stub完全不是同一个对象,所以send的stub永远匹配不上条件,自然不会返回fakeFrame,也不会触发回调逻辑。
写法一:用callsFake直接处理回调
const fakeFrame = { write: sinon.stub(), end: sinon.stub() }; const fakeClient = { connect: sinon.stub(), disconnect: sinon.stub() }; // 重写send的stub逻辑,直接获取并调用传入的onReceipt fakeClient.send = sinon.stub().callsFake((destination, options) => { // 触发业务代码里的onReceipt回调 if (typeof options.onReceipt === 'function') { // 如果业务代码需要receipt帧参数,可以在这里传入模拟的帧对象 options.onReceipt(); } return fakeFrame; });
写法二:用Sinon匹配器+callsFake
如果想保留withArgs的匹配逻辑,改用Sinon的通用匹配器来检查options结构:
const fakeFrame = { write: sinon.stub(), end: sinon.stub() }; const fakeClient = { connect: sinon.stub(), disconnect: sinon.stub(), send: sinon.stub() .withArgs( sinon.match.any, // 匹配任意destination参数 sinon.match.has('onReceipt', sinon.match.func) // 匹配包含onReceipt函数的options ) .callsFake((dest, options) => { options.onReceipt(); // 触发回调 return fakeFrame; }) };
这样修改后,只要业务代码传入的options里带有onReceipt函数,就能匹配到stub,触发回调后,Promise会正常resolve,client.disconnect()也会被调用,测试逻辑就能正常执行。
内容的提问来源于stack exchange,提问作者BinaryDigit
相关产品推荐
相关产品推荐

