Skip to content

Commit bde1204

Browse files
author
George Schneeloch
committed
Add support for passing a function to stub.throws(...).
1 parent 5daa737 commit bde1204

File tree

4 files changed

+88
-4
lines changed

4 files changed

+88
-4
lines changed

docs/release-source/release/stubs.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,11 @@ Causes the stub to throw an exception of the provided type.
271271
Causes the stub to throw the provided exception object.
272272

273273

274+
#### `stub.throws(function() { return new Error(); });`
275+
276+
Causes the stub to throw the exception returned by the function.
277+
278+
274279
#### `stub.rejects();`
275280

276281
Causes the stub to return a Promise which rejects with an exception (`Error`).

lib/sinon/behavior.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ var proto = {
127127

128128
if (this.exception) {
129129
throw this.exception;
130+
} else if (this.exceptionCreator) {
131+
this.exception = this.exceptionCreator();
132+
this.exceptionCreator = undefined;
133+
throw this.exception;
130134
} else if (typeof this.returnArgAt === "number") {
131135
return args[this.returnArgAt];
132136
} else if (this.returnThis) {

lib/sinon/default-behaviors.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@ var useLeftMostCallback = -1;
77
var useRightMostCallback = -2;
88

99
function throwsException(fake, error, message) {
10-
if (typeof error === "string") {
11-
fake.exception = new Error(message || "");
12-
fake.exception.name = error;
10+
if (typeof error === "function") {
11+
fake.exceptionCreator = error;
12+
} else if (typeof error === "string") {
13+
fake.exceptionCreator = function () {
14+
var newException = new Error(message || "");
15+
newException.name = error;
16+
return newException;
17+
};
1318
} else if (!error) {
14-
fake.exception = new Error("Error");
19+
fake.exceptionCreator = function () {
20+
return new Error("Error");
21+
};
1522
} else {
1623
fake.exception = error;
1724
}
@@ -129,6 +136,7 @@ module.exports = {
129136
fake.reject = false;
130137
fake.returnValueDefined = true;
131138
fake.exception = undefined;
139+
fake.exceptionCreator = undefined;
132140
fake.fakeFn = undefined;
133141
},
134142

@@ -158,6 +166,7 @@ module.exports = {
158166
fake.reject = false;
159167
fake.returnValueDefined = true;
160168
fake.exception = undefined;
169+
fake.exceptionCreator = undefined;
161170
fake.fakeFn = undefined;
162171
},
163172

@@ -176,6 +185,7 @@ module.exports = {
176185
fake.reject = true;
177186
fake.returnValueDefined = true;
178187
fake.exception = undefined;
188+
fake.exceptionCreator = undefined;
179189
fake.fakeFn = undefined;
180190

181191
return fake;

test/stub-test.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,43 @@ describe("stub", function () {
513513
assert.exception(stub, "Error");
514514
});
515515

516+
it("uses a lazily created exception for the generic error", function () {
517+
var stub = createStub.create();
518+
stub.throws();
519+
520+
assert.isFunction(stub.defaultBehavior.exceptionCreator);
521+
assert(stub.defaultBehavior.exception === undefined);
522+
assert.exception(stub, "Error");
523+
assert(stub.defaultBehavior.exceptionCreator === undefined);
524+
assert.same(stub.firstCall.exception.name, "Error");
525+
});
526+
527+
it("uses a lazily created exception for the named error", function () {
528+
var stub = createStub.create();
529+
stub.throws("TypeError", "typeerror message");
530+
531+
assert.isFunction(stub.defaultBehavior.exceptionCreator);
532+
assert(stub.defaultBehavior.exception === undefined);
533+
assert.exception(stub, {
534+
name: "TypeError",
535+
message: "typeerror message"
536+
});
537+
assert(stub.defaultBehavior.exceptionCreator === undefined);
538+
assert.same(stub.firstCall.exception.name, "TypeError");
539+
});
540+
541+
it("does not use a lazily created exception if the error object is provided", function () {
542+
var stub = createStub.create();
543+
var exception = new Error();
544+
stub.throws(exception);
545+
546+
assert(stub.defaultBehavior.exceptionCreator === undefined);
547+
assert(stub.defaultBehavior.exception === exception);
548+
assert.exception(stub, exception);
549+
assert(stub.defaultBehavior.exceptionCreator === undefined);
550+
assert(stub.defaultBehavior.exception === exception);
551+
});
552+
516553
it("resets 'invoking' flag", function () {
517554
var stub = createStub.create();
518555
stub.throws();
@@ -521,6 +558,23 @@ describe("stub", function () {
521558

522559
refute.defined(stub.invoking);
523560
});
561+
562+
it("throws an exception created using a function", function () {
563+
var stub = createStub.create();
564+
565+
stub.throws(function () {
566+
return new Error("not implemented");
567+
});
568+
569+
assert.isFunction(stub.defaultBehavior.exceptionCreator);
570+
assert(stub.defaultBehavior.exception === undefined);
571+
assert.exception(stub, {
572+
message: "not implemented"
573+
});
574+
assert(stub.defaultBehavior.exceptionCreator === undefined);
575+
assert.same(stub.firstCall.exception.message, "not implemented");
576+
assert.contains(stub.firstCall.toString(), "not implemented");
577+
});
524578
});
525579

526580
describe(".callsArg", function () {
@@ -872,6 +926,17 @@ describe("stub", function () {
872926
assert(stub.threw("TypeError"));
873927
});
874928

929+
it("handles threw properly for lazily instantiated Errors", function () {
930+
var stub = createStub(this.object, "method");
931+
stub.throws(function () {
932+
return new TypeError();
933+
});
934+
935+
assert.exception(this.object.method);
936+
937+
assert(stub.threw("TypeError"));
938+
});
939+
875940
it("returns standalone stub without arguments", function () {
876941
var stub = createStub();
877942

0 commit comments

Comments
 (0)