如何解决Sinon replace报错 强制覆写已被替换的Mock方法
Sinon重复替换已Mock方法的解决方案
核心结论
Sinon 的 sandbox.replace 没有内置 force 类参数直接强制覆写已替换的方法,但可以通过以下两种方案实现仅覆写指定方法、不影响其他Mock配置的需求:
方案1:单独恢复目标方法后重新替换
sandbox.restore 支持传入「目标对象+属性名」作为参数,仅恢复单个属性的Mock配置,不会触达沙箱内其他替换逻辑,恢复后即可重新调用 replace 完成覆写:
it("should do what I tell it", async () => { { // part1 仅恢复foo.foo,bar的Mock不受影响 sandbox.restore(foo, "foo"); sandbox.replace(foo, "foo", async function* () { yield { error: undefined, data: { hello: "world2" } }; }); // ... 断言逻辑 } { // part2 同理操作 sandbox.restore(foo, "foo"); sandbox.replace(foo, "foo", async function* () { yield { error: undefined, data: { hello: "world3" } }; }); // ... 断言逻辑 } });
方案2(推荐):使用Stub动态修改行为
这是符合Sinon最佳实践的方案,无需重复调用replace。初始替换时直接用Sinon Stub作为替换值,保存Stub引用后可随时通过callsFake等方法动态修改行为,完全不会触发重复替换报错:
代码改造示例
- 先在测试块作用域声明Stub变量
describe("sync", () => { let sandbox: sinon.SinonSandbox; let fooStub: sinon.SinonStub; // 新增stub引用变量
beforeEach中用Stub替换原方法
beforeEach(async () => { sandbox = sinon.createSandbox(); sandbox.replace(bar, "bar", () => {}); // 用Stub作为替换值,绑定初始行为并保存引用 fooStub = sandbox.stub(foo, "foo").callsFake(async function* () { yield { error: undefined, data: { hello: "world" } }; }); });
- 测试用例中直接修改Stub行为即可
it("should do what I tell it", async () => { { // part1 直接重写Stub行为,无需恢复/重新替换 fooStub.callsFake(async function* () { yield { error: undefined, data: { hello: "world2" } }; }); // ... 断言逻辑 } { // part2 同理直接修改 fooStub.callsFake(async function* () { yield { error: undefined, data: { hello: "world3" } }; }); // ... 断言逻辑 } });
内容的提问来源于stack exchange,提问作者david_adler
相关产品推荐
相关产品推荐

