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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:24:02