#2760·sinon

createStubInstance() 没有接收每个沙箱调用 ID 的上下文,导致 calledAfter/calledBefore 与 spy() 之间出现问题

作者: rlsf创建于 2026年8月9日更新于 2026年8月9日

描述错误

22.1.0 版本引入了针对并行测试的沙箱 callId 隔离 ( #2472, 由 #2715 修复)。通过 sandbox.spy() / sandbox.stub() 创建的模拟现在通过 .withContext(...) 从一个隔离的 sandboxContext 对象中获取 callId。然而,createStubInstance() (包括顶层的 sinon.createStubInstance()sandbox.createStubInstance()) 并未作为该修复的一部分进行更新。它仍然内部调用普通的 stub(stubInstance) (参见 create-stub-instance.js / stub.js),该函数从来没有接收上下文,因此会回退到 proxy-invoke.js 中的硬编码的模块级单例 defaultContext = { callId: 0 } 中。实际效果是:通过 createStubInstance() 创建的任何模拟都会在与通过 spy() / stub() 创建的模拟完全不同的 callId 计数器上进行跟踪。两个计数器都独立地从 0 开始,因此通过 createStubInstance() 创建的方法与通过 spy() / stub() 创建的模拟之间的 calledAfter() / calledBefore() / calledImmediatelyBefore() / calledImmediatelyAfter() 比较变得毫无意义 - 它们不再反映真实的调用顺序。在 22.1.0 之前,情况是正确的,因为所有东西共享一个全局 callId 计数器。