Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow providing stubs overrides for sinon.createStubInstance #1864

Merged
merged 2 commits into from Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 31 additions & 1 deletion docs/release-source/release/stubs.md
Expand Up @@ -95,7 +95,37 @@ Stubbing individual methods tests intent more precisely and is less susceptible
If you want to create a stub object of `MyConstructor`, but don't want the constructor to be invoked, use this utility function.

```javascript
var stub = sinon.createStubInstance(MyConstructor)
var stub = sinon.createStubInstance(MyConstructor, overrides);
```

`overrides` is an optional map overriding created stubs, for example:

```javascript

var stub = sinon.createStubInstance(MyConstructor, {
foo: sinon.stub().returnsThis()
});
```

is the same as:

```javascript
var stub = sinon.createStubInstance(MyConstructor);
stub.foo.returnsThis();
```

If provided value is not a stub, it will be used as the returned value:

```javascript
var stub = sinon.createStubInstance(MyConstructor, {
foo: 3
});
```
is the same as:

```javascript
var stub = sinon.createStubInstance(MyConstructor);
stub.foo.returns(3);
```

#### `stub.withArgs(arg1[, arg2, ...]);`
Expand Down
21 changes: 19 additions & 2 deletions lib/sinon/stub.js
Expand Up @@ -66,11 +66,28 @@ function stub(object, property) {
return isStubbingNonFuncProperty ? s : wrapMethod(object, property, s);
}

stub.createStubInstance = function (constructor) {
stub.createStubInstance = function (constructor, overrides) {
if (typeof constructor !== "function") {
throw new TypeError("The constructor should be a function.");
}
return stub(Object.create(constructor.prototype));

var stubbedObject = stub(Object.create(constructor.prototype));

Object.keys(overrides || {}).forEach(function (propertyName) {
if (propertyName in stubbedObject) {
var value = overrides[propertyName];
if (value.createStubInstance) {
stubbedObject[propertyName] = value;
}
else {
stubbedObject[propertyName].returns(value);
}
}
else {
throw new Error("Cannot stub " + propertyName + ". Property does not exist!");
}
});
return stubbedObject;
};

/*eslint-disable no-use-before-define*/
Expand Down
33 changes: 33 additions & 0 deletions test/stub-test.js
Expand Up @@ -2755,6 +2755,39 @@ describe("stub", function () {
});
}
});

it("allows providing optional overrides", function () {
var Class = function () {};
Class.prototype.method = function () {};

var stub = createStubInstance(Class, {
method: createStub().returns(3)
});

assert.equals(3, stub.method());
});

it("allows providing optional returned values", function () {
var Class = function () {};
Class.prototype.method = function () {};

var stub = createStubInstance(Class, {
method: 3
});

assert.equals(3, stub.method());
});

it("throws an exception when trying to override non-existing property", function () {
var Class = function () {};
Class.prototype.method = function () {};

assert.exception(function () {
createStubInstance(Class, {
foo: createStub().returns(3)
});
}, {message: "Cannot stub foo. Property does not exist!"});
});
});

describe(".callThrough", function () {
Expand Down