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

Sinon单元测试中如何为单个Stub实现动态返回不同测试结果

Sinon实现Stub动态随机返回值的解决方案

问题核心原因

你当前遇到的stub返回值固定问题,本质是JavaScript的参数即时求值逻辑导致的:

  • 当你写sinon.stub(dynamodb, 'get').resolves(stubGet())时,代码执行到打桩这一步,就会立刻运行stubGet()一次,把这次跑出来的结果当成固定参数传给.resolves()
  • 后面不管业务代码调用多少次打桩的get方法,拿到的都是这个提前算好的固定值,根本不会再触发stubGet的运行
  • 你之前了解的.onCall()语法也不适用,因为它所有的预设返回值,都是在打桩初始化时就一次性全部生成好的,没法在方法被调用的瞬间动态计算返回结果。

适配需求的实现方式

想要实现每次stub被调用时,实时生成随机返回值、动态覆盖各类分支,不需要用固定值预设的语法,直接通过callsFake给stub绑定自定义的异步实现即可,这种模式下所有逻辑都会在stub被实际调用时才执行。
修改后的打桩代码示例:

sinon.stub(dynamodb, 'get').callsFake(async () => {
  // 以下逻辑每次stub被调用时才会执行,不会提前运行
  const i = Math.round(Math.random() * sampleData.length)
  const repo = sampleData[i]

  // 随机命中是否带新推送时间的分支
  const isNew = Math.round(Math.random()) === 1
  if (isNew) {
    repo.pushed_at = { S: '1970-01-01T00:00:00Z' }
  }

  console.log('repo', repo)
  const item = { Item: repo }
  console.log(item)
  return item
})

方案特性

  • 完全匹配你的随机测试数据生成需求:每次stub被触发时,才会执行随机数生成、分支判断的逻辑,不会出现初始化阶段固定返回的问题
  • 灵活度更高:自定义的fake函数可以直接接收stub方法的调用入参,支持基于入参的动态返回逻辑,比固定索引匹配的onCall能力更强
  • 异步行为兼容:通过async函数实现的fake,会自动将返回值包装为已resolve的Promise,和你之前使用的.resolves()的异步效果完全一致,不需要改动业务侧的异步调用代码

如果不想把原有stubGet的逻辑全部挪到fake函数内部,也可以用更简洁的写法:sinon.stub(dynamodb, 'get').callsFake(() => Promise.resolve(stubGet())),运行效果和上面的写法完全一致。

内容的提问来源于stack exchange,提问作者gvasquez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 09:36:04