如何使用Sinon mock异步场景下的链式函数调用
Sinon 异步链式调用场景Mock方案
你要模拟的是两层异步+链式调用的结构,核心思路是从顶层方法开始逐层mock每一层的返回值:先mockgetData方法的异步返回结果,返回的对象要包含collection方法;再让collection方法的返回结果包含异步的deleteOne方法即可。
完整测试示例
假设getData是从你自己的业务模块./db.js中导出的,测试代码如下:
const sinon = require('sinon'); // 替换为你实际的getData所属模块路径 const db = require('./db'); it('should delete target document correctly', async () => { // 1. 先mock最底层的deleteOne方法,自定义返回结果 const mockDeleteResult = { deletedCount: 1 }; const deleteOneStub = sinon.stub().resolves(mockDeleteResult); // 2. mock collection方法,匹配入参'myCollection'时返回带deleteOne的对象 const collectionStub = sinon.stub(); collectionStub.withArgs('myCollection').returns({ deleteOne: deleteOneStub }); // 3. mock顶层的getData方法,返回带collection方法的对象 const getDataStub = sinon.stub(db, 'getData').resolves({ collection: collectionStub }); // 执行你要测试的业务代码 const data = await db.getData(); const res = await data.collection('myCollection').deleteOne({ id: 12 }); // 调用校验(可根据你的测试需求选择) // 校验getData被调用 sinon.assert.calledOnce(getDataStub); // 校验collection传入了正确的集合名称 sinon.assert.calledWithExactly(collectionStub, 'myCollection'); // 校验deleteOne传入了正确的筛选条件 sinon.assert.calledWithExactly(deleteOneStub, { id: 12 }); // 测试完成后恢复原方法,避免影响其他用例 getDataStub.restore(); });
补充说明
如果getData是全局挂载的方法而非模块导出,修改stub的挂载对象即可:Node环境替换为global,浏览器环境替换为window。
内容的提问来源于stack exchange,提问作者cam
相关产品推荐
相关产品推荐

