From a2110fc3fde69efc7367f77b89d0f3cc8282089e Mon Sep 17 00:00:00 2001 From: Kevin Bosman Date: Wed, 14 Aug 2019 21:23:51 +0200 Subject: [PATCH] Restore sinon.createStubInstance() behaviour (#2073) PR #2022 redirected sinon.createStubInstance() to use the Sandbox implementation thereof. This introduced a breaking change due to the sandbox implementation not supporting property overrides. Instead of duplicating the original behaviour from stub.js into sandbox.js, call through to the stub.js implementation then add all the stubs to the sandbox collection as usual. Copy the missing tests from stub-test.js and add issue tests. --- lib/sinon/sandbox.js | 17 +++++++--- test/issues/issues-test.js | 23 ++++++++++++++ test/sandbox-test.js | 65 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/lib/sinon/sandbox.js b/lib/sinon/sandbox.js index 8a9123b5e..9d2bc007f 100644 --- a/lib/sinon/sandbox.js +++ b/lib/sinon/sandbox.js @@ -51,11 +51,18 @@ function Sandbox() { return fakeRestorers; }; - sandbox.createStubInstance = function createStubInstance(constructor) { - if (typeof constructor !== "function") { - throw new TypeError("The constructor should be a function."); - } - return this.stub(Object.create(constructor.prototype)); + sandbox.createStubInstance = function createStubInstance() { + var stubbed = sinonStub.createStubInstance.apply(null, arguments); + + var ownMethods = collectOwnMethods(stubbed); + + forEach(ownMethods, function(method) { + push(collection, method); + }); + + usePromiseLibrary(promiseLib, ownMethods); + + return stubbed; }; sandbox.inject = function inject(obj) { diff --git a/test/issues/issues-test.js b/test/issues/issues-test.js index 48a59da15..43b20b7ed 100644 --- a/test/issues/issues-test.js +++ b/test/issues/issues-test.js @@ -657,4 +657,27 @@ describe("issues", function() { }); }); }); + + describe("#2073 - sinon.createStubInstance()", function() { + function Foo() { + return; + } + Foo.prototype.testMethod = function() { + return 1; + }; + + it("should override the method", function() { + var thing = sinon.createStubInstance(Foo, { + testMethod: sinon.stub().returns(2) + }); + assert.equals(thing.testMethod(), 2); + }); + + it("should support calling without object binding", function() { + var createStubInstance = sinon.createStubInstance; + refute.exception(function() { + createStubInstance(Foo); + }); + }); + }); }); diff --git a/test/sandbox-test.js b/test/sandbox-test.js index e8716521b..d8ddb7639 100644 --- a/test/sandbox-test.js +++ b/test/sandbox-test.js @@ -280,6 +280,71 @@ describe("Sandbox", function() { }); } }); + + it("allows providing optional overrides", function() { + var Class = function() { + return; + }; + Class.prototype.method = function() { + return; + }; + + var stub = this.sandbox.createStubInstance(Class, { + method: sinonStub().returns(3) + }); + + assert.equals(3, stub.method()); + }); + + it("allows providing optional returned values", function() { + var Class = function() { + return; + }; + Class.prototype.method = function() { + return; + }; + + var stub = this.sandbox.createStubInstance(Class, { + method: 3 + }); + + assert.equals(3, stub.method()); + }); + + it("allows providing null as a return value", function() { + var Class = function() { + return; + }; + Class.prototype.method = function() { + return; + }; + + var stub = this.sandbox.createStubInstance(Class, { + method: null + }); + + assert.equals(null, stub.method()); + }); + + it("throws an exception when trying to override non-existing property", function() { + var Class = function() { + return; + }; + Class.prototype.method = function() { + return; + }; + + var sandbox = this.sandbox; + + assert.exception( + function() { + sandbox.createStubInstance(Class, { + foo: sinonStub().returns(3) + }); + }, + { message: "Cannot stub foo. Property does not exist!" } + ); + }); }); describe(".stub", function() {