From 56ca44f27e63e5fdc326b43550e479e4329fbaef Mon Sep 17 00:00:00 2001 From: George Schneeloch Date: Thu, 3 Aug 2017 11:27:57 -0400 Subject: [PATCH] Add support for passing a function to stub.throws(...). --- docs/release-source/release/stubs.md | 5 +++++ lib/sinon/behavior.js | 4 ++++ lib/sinon/default-behaviors.js | 18 ++++++++++++++---- test/stub-test.js | 27 +++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/docs/release-source/release/stubs.md b/docs/release-source/release/stubs.md index c1c5bd47f..2197723ea 100644 --- a/docs/release-source/release/stubs.md +++ b/docs/release-source/release/stubs.md @@ -271,6 +271,11 @@ Causes the stub to throw an exception of the provided type. Causes the stub to throw the provided exception object. +#### `stub.throws(function() { return new Error(); });` + +Causes the stub to throw the function returned by the function. + + #### `stub.rejects();` Causes the stub to return a Promise which rejects with an exception (`Error`). diff --git a/lib/sinon/behavior.js b/lib/sinon/behavior.js index 489da3b36..640261fe8 100644 --- a/lib/sinon/behavior.js +++ b/lib/sinon/behavior.js @@ -127,6 +127,10 @@ var proto = { if (this.exception) { throw this.exception; + } else if (this.exceptionCreator) { + this.exception = this.exceptionCreator(); + this.exceptionCreator = undefined; + throw this.exception; } else if (typeof this.returnArgAt === "number") { return args[this.returnArgAt]; } else if (this.returnThis) { diff --git a/lib/sinon/default-behaviors.js b/lib/sinon/default-behaviors.js index 13a8ce7b7..46e4f160e 100644 --- a/lib/sinon/default-behaviors.js +++ b/lib/sinon/default-behaviors.js @@ -7,11 +7,18 @@ var useLeftMostCallback = -1; var useRightMostCallback = -2; function throwsException(fake, error, message) { - if (typeof error === "string") { - fake.exception = new Error(message || ""); - fake.exception.name = error; + if (typeof error === "function") { + fake.exceptionCreator = error; + } else if (typeof error === "string") { + fake.exceptionCreator = function () { + var newException = new Error(message || ""); + newException.name = error; + return newException; + }; } else if (!error) { - fake.exception = new Error("Error"); + fake.exceptionCreator = function () { + return new Error("Error"); + }; } else { fake.exception = error; } @@ -129,6 +136,7 @@ module.exports = { fake.reject = false; fake.returnValueDefined = true; fake.exception = undefined; + fake.exceptionCreator = undefined; fake.fakeFn = undefined; }, @@ -158,6 +166,7 @@ module.exports = { fake.reject = false; fake.returnValueDefined = true; fake.exception = undefined; + fake.exceptionCreator = undefined; fake.fakeFn = undefined; }, @@ -176,6 +185,7 @@ module.exports = { fake.reject = true; fake.returnValueDefined = true; fake.exception = undefined; + fake.exceptionCreator = undefined; fake.fakeFn = undefined; return fake; diff --git a/test/stub-test.js b/test/stub-test.js index 19579aebc..fd236ea88 100644 --- a/test/stub-test.js +++ b/test/stub-test.js @@ -521,6 +521,22 @@ describe("stub", function () { refute.defined(stub.invoking); }); + + it("throws an exception created using a function", function () { + var stub = createStub.create(); + + function namedFunc() { + return new Error("not implemented"); + } + + stub.throws(namedFunc); + + assert.exception(stub, { + message: "not implemented" + }); + assert.same(stub.firstCall.exception.message, "not implemented"); + assert.contains(stub.firstCall.toString(), "not implemented"); + }); }); describe(".callsArg", function () { @@ -872,6 +888,17 @@ describe("stub", function () { assert(stub.threw("TypeError")); }); + it("handles threw properly for lazily instantiated Errors", function () { + var stub = createStub(this.object, "method"); + stub.throws(function () { + return new TypeError(); + }); + + assert.exception(this.object.method); + + assert(stub.threw("TypeError")); + }); + it("returns standalone stub without arguments", function () { var stub = createStub();