Skip to content

Commit

Permalink
Allow providing stubs overrides for sinon.createStubInstance (sinonjs…
Browse files Browse the repository at this point in the history
  • Loading branch information
ifrost authored and Franck Romano committed Oct 1, 2019
1 parent fb417d3 commit d49e25d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
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 @@ -71,11 +71,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

0 comments on commit d49e25d

Please sign in to comment.