Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add support for passing a function to stub.throws(...). (#1511)
  • Loading branch information
George Schneeloch authored and mantoni committed Aug 6, 2017
1 parent 5daa737 commit ec74e94
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 4 deletions.
5 changes: 5 additions & 0 deletions docs/release-source/release/stubs.md
Expand Up @@ -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 exception returned by the function.


#### `stub.rejects();`

Causes the stub to return a Promise which rejects with an exception (`Error`).
Expand Down
4 changes: 4 additions & 0 deletions lib/sinon/behavior.js
Expand Up @@ -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) {
Expand Down
18 changes: 14 additions & 4 deletions lib/sinon/default-behaviors.js
Expand Up @@ -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;
}
Expand Down Expand Up @@ -129,6 +136,7 @@ module.exports = {
fake.reject = false;
fake.returnValueDefined = true;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;
},

Expand Down Expand Up @@ -158,6 +166,7 @@ module.exports = {
fake.reject = false;
fake.returnValueDefined = true;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;
},

Expand All @@ -176,6 +185,7 @@ module.exports = {
fake.reject = true;
fake.returnValueDefined = true;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;

return fake;
Expand Down
85 changes: 85 additions & 0 deletions test/stub-test.js
Expand Up @@ -513,6 +513,80 @@ describe("stub", function () {
assert.exception(stub, "Error");
});

it("throws an exception created using a function", function () {
var stub = createStub.create();

stub.throws(function () {
return new Error("not implemented");
});

assert.exception(stub, {
message: "not implemented"
});
assert.same(stub.firstCall.exception.message, "not implemented");
assert.contains(stub.firstCall.toString(), "not implemented");
});

describe("lazy instantiation of exceptions", function () {
var errorSpy;
beforeEach(function () {
this.originalError = global.Error;
errorSpy = createSpy(global, "Error");
// errorSpy starts with a call already made, not sure why
errorSpy.reset();
});

afterEach(function () {
errorSpy.restore();
global.Error = this.originalError;
});

it("uses a lazily created exception for the generic error", function () {
var stub = createStub.create();
stub.throws();

assert.isFalse(errorSpy.called);
assert.exception(stub, "Error");
assert.isTrue(errorSpy.called);
});

it("uses a lazily created exception for the named error", function () {
var stub = createStub.create();
stub.throws("TypeError", "typeerror message");

assert.isFalse(errorSpy.called);
assert.exception(stub, {
name: "TypeError",
message: "typeerror message"
});
assert.isTrue(errorSpy.called);
});

it("uses a lazily created exception provided by a function", function () {
var stub = createStub.create();

stub.throws(function () {
return new Error("not implemented");
});

assert.isFalse(errorSpy.called);
assert.exception(stub, {
message: "not implemented"
});
assert.isTrue(errorSpy.called);
});

it("does not use a lazily created exception if the error object is provided", function () {
var stub = createStub.create();
var exception = new Error();
stub.throws(exception);

assert.same(errorSpy.callCount, 1);
assert.exception(stub, exception);
assert.same(errorSpy.callCount, 1);
});
});

it("resets 'invoking' flag", function () {
var stub = createStub.create();
stub.throws();
Expand Down Expand Up @@ -872,6 +946,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();

Expand Down

0 comments on commit ec74e94

Please sign in to comment.