19

If I have create a instance by var a = sinon.createStubInstance(MyContructor).

How can I replace one of the stubbed function like var stub = sinon.stub(object, "method", func);.

The main reason I am doing this is want to achieve multiple callback workaround as this mentioned

Community
  • 1
  • 1
StevenR
  • 702
  • 1
  • 8
  • 17

4 Answers4

21

The method you mentioned (sinon.stub(object, "method", func)) is a method that was available in version 1.x, and did the following according to the documentation:

Replaces object.method with a func, wrapped in a spy. As usual, object.method.restore(); can be used to restore the original method.

However, if you're using sinon.createStubInstance(), all methods are already stubbed. That means you can already do certain things with the stubbed instance. For example:

function Person(firstname, lastname) {
  this.firstname = firstname;
  this.lastname = lastname;
}
Person.prototype.getName = function() {
  return this.firstname + " " + this.lastname;
}

const p = sinon.createStubInstance(Person);
p.getName.returns("Alex Smith");

console.log(p.getName()); // "Alex Smith"

If you really want to replace a stub by another spy or stub, you could assign the property to a new stub or spy:

const p = sinon.createStubInstance(Person);
p.getName = sinon.spy(function() { return "Alex Smith"; }); // Using a spy
p.getName = sinon.stub(); // OR using a stub

With Sinon.js 2.x and higher, it's even easier to replace a stubbed function by using the callsFake() function:

p.getName.callsFake(function() { return "Alex Smith"; });
g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • Before one calls, a.method = sinon.stub(), it is important to call a.method.restore(). – Ajitesh May 13 '17 at 11:40
  • 9
    Up-voted as this answer got me on the right track. Although since this was answered `sinon.stub(object, "method", fn)` has been deprecated. We can now use `sinon.stub(object, "method").callsFake(function() { // do stuff });` See [here](http://sinonjs.org/releases/v2.3.1/stubs#stubcallsfakefakefunction) _Edit: fixed url_ – Phil D. Oct 11 '17 at 10:48
  • @PhilD. You're right, but the question itself is asking for `sinon.stub(object, "method", fn)`, so I think I won't be including that information in the answer itself. – g00glen00b Oct 11 '17 at 11:12
  • @g00glen00b, yes, but it takes everyone who comes here an extra iteration, to go back to code, learn that there is no third argument, return here for comments or dig deeper. I think everyone would benefit from an update section in the answer – Kirill Slatin Sep 22 '20 at 05:31
  • @KirillSlatin Within the original state of this answer and the question I found it difficult to integrate it and still keep the answer on topic to the question. However, I tried to rewrite the answer so that I could integrate that part into my answer. – g00glen00b Sep 22 '20 at 08:09
  • @g00glen00b thanks for update! It looks good to me. You could also add an **Update** section as it is natural that since you answered in 2015 API/library evolved and now there is a nuance to the proposed solution. It is comprehended properly by readers and a tradition on SO – Kirill Slatin Sep 23 '20 at 10:26
14

After stubbing a whole object using sinon.createStubInstance(MyConstructor) or sinon.stub(obj) you can only replace the stub by either assigning a new stub to the property (as described by @g00glen00b) or restoring the stub before re-stubbing.

var a = sinon.createStubInstance(MyConstructor);
a.method.restore();
sinon.stub(object, "method", func);

The advantage of this is that you can still call a.method.restore() afterwards with the expected behavior.

It would be more convenient if the Stub API had a .call(func) method to override the function being called by the stub after the fact.

flungo
  • 1,050
  • 1
  • 7
  • 21
3

There's no need to overwrite the a.method, instead we can use callsFake on the a.method directly:

const a = sinon.createStubInstance(MyContructor);
a.method.callsFake(func);
Jan Molak
  • 4,426
  • 2
  • 36
  • 32
1

1 more way to stub the method from 2.0 +

sinon.stub(object, "method").callsFake(func);

object.method.restore()
Srini
  • 708
  • 1
  • 8
  • 23