From 2a3696d51e4b2d4bd773038cc00c323062a8fd2b Mon Sep 17 00:00:00 2001 From: Morgan Roderick Date: Wed, 2 May 2018 10:01:26 +0200 Subject: [PATCH] Fix #1775: Default sandbox does not restore stubs, spies, mocks This was caused by adding stub, spy, mock explicitly to apiMethods, thus shadowing the methods from Sanbox, which are the ones that collect the fakes for restoring. Removing these methods, allows the caller to use the sandbox methods, and all is well. --- lib/sinon.js | 3 --- lib/sinon/sandbox.js | 5 +++++ test/issues/issues-test.js | 46 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/lib/sinon.js b/lib/sinon.js index d885b727c..a0b171d05 100644 --- a/lib/sinon.js +++ b/lib/sinon.js @@ -15,10 +15,7 @@ var apiMethods = { assert: require("./sinon/assert"), fake: require("./sinon/fake"), match: require("./sinon/match"), - spy: require("./sinon/spy"), spyCall: require("./sinon/call"), - stub: require("./sinon/stub"), - mock: require("./sinon/mock"), expectation: require("./sinon/mock-expectation"), createStubInstance: require("./sinon/stub").createStubInstance, diff --git a/lib/sinon/sandbox.js b/lib/sinon/sandbox.js index 7c313bef6..fce6468f2 100644 --- a/lib/sinon/sandbox.js +++ b/lib/sinon/sandbox.js @@ -2,6 +2,7 @@ var collectOwnMethods = require("./collect-own-methods"); var getPropertyDescriptor = require("./util/core/get-property-descriptor"); +var isEsModule = require("./util/core/is-es-module"); var isPropertyConfigurable = require("./util/core/is-property-configurable"); var isNonExistentOwnProperty = require("./util/core/is-non-existent-own-property"); var sinonMatch = require("./match"); @@ -258,6 +259,10 @@ function Sandbox() { }; sandbox.stub = function stub(object, property) { + if (isEsModule(object)) { + throw new TypeError("ES Modules cannot be stubbed"); + } + if (isNonExistentOwnProperty(object, property)) { throw new TypeError("Cannot stub non-existent own property " + valueToString(property)); } diff --git a/test/issues/issues-test.js b/test/issues/issues-test.js index 48b76bd3f..0c3d84433 100644 --- a/test/issues/issues-test.js +++ b/test/issues/issues-test.js @@ -420,4 +420,50 @@ describe("issues", function () { refute.isTrue(spyProp.get.called); }); }); + + // this error was caused by overwriting methods with imported ones don't use the collection + // and thus were not restorable + describe("#1775 - sinon.restore", function () { + it("should restore all stubs", function () { + var myApi = { + someMethod: function someMethod() { + // eslint-disable-next-line no-console + console.log("test method!"); + } + }; + + sinon.stub(myApi, "someMethod"); + sinon.restore(); + sinon.stub(myApi, "someMethod"); + // TypeError: Attempted to wrap someMethod which is already wrapped + }); + + it("should restore all spies", function () { + var myApi = { + someMethod: function someMethod() { + // eslint-disable-next-line no-console + console.log("test method!"); + } + }; + + sinon.spy(myApi, "someMethod"); + sinon.restore(); + sinon.spy(myApi, "someMethod"); + // TypeError: Attempted to wrap someMethod which is already wrapped + }); + + it("should restore all mocks", function () { + var myApi = { + someMethod: function someMethod() { + // eslint-disable-next-line no-console + console.log("test method!"); + } + }; + + sinon.mock(myApi); + sinon.restore(); + sinon.mock(myApi); + // TypeError: Attempted to wrap someMethod which is already wrapped + }); + }); });