Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sinon.js stub - can you call more than one callback on a single stubbed function?

If I have a stub for a function that takes 2 callbacks, how can I wire up sinon.js to call both callbacks when the stubbed function is invoked?

For example - here's function that I want to stub which takes 2 functions as arguments:

function stubThisThing(one, two) {
   ... one and two are functions ...
   ... contents stubbed by sinon.js ...
}

I can use sinon to call either one of the arguments:

stubbedThing.callsArg(0);

or

stubbedThing.callsArg(1);

but I can't seem to get both to be called. If I try:

stubbedThing.callsArg(0).callsArg(1);

or

stubbedThing.callsArg(0);
stubbedThing.callsArg(1);

then sinon will only ever call the second argument. If I wire it up in the other order, then sinon will call the first arg. However, I'd like both to be called one after the other.

like image 201
serg10 Avatar asked Apr 23 '15 09:04

serg10


People also ask

What is callsFake in Sinon stub?

stub . In Sinon, a fake is a Function that records arguments, return value, the value of this and exception thrown (if any) for all of its calls. A fake is immutable: once created, the behavior will not change. Unlike sinon. spy and sinon.

When would you want to use a stub function in Javascript?

A test stub is a function or object that replaces the actual behavior of a module with a fixed response. The stub can only return the fixed response it was programmed to return.

What does sandbox stub do?

sandbox.Causes all stubs and mocks created from the sandbox to return promises using a specific Promise library instead of the global one when using stub. rejects or stub. resolves . Returns the stub to allow chaining.

How to make a Sinon stub respond differently on consecutive calls?

As of Sinon version 1.8, you can use the onCall method to make a stub respond differently on consecutive calls. Note that in Sinon version 1.5 to version 1.7, multiple calls to the yields* and callsArg* family of methods define a sequence of behaviors for consecutive calls. As of 1.8, this functionality has been removed in favor of the onCall API.

How do you call multiple callbacks from a stub?

Causes the stub to call the first callback it receives with the provided arguments (if any). If a method accepts more than one callback, you need to use yieldsRight to call the last callback or callsArg to have the stub invoke other callbacks than the first or last one.

What are stubs in JavaScript?

As spies, stubs can be either anonymous, or wrap existing functions. When wrapping an existing function with a stub, the original function is not called. When to use stubs?

What is a Sinon stub?

The sinon.stub () substitutes the real function and returns a stub object that you can configure using methods like callsFake () . Stubs also have a callCount property that tells you how many times the stub was called.


2 Answers

This is not a classic scenario, since not many methods would call two methods sequentially, and I guess thats why it isn't supported. But, be calm, the solution is easy:

var subject = { 
    method: function(one, two) {} 
};

var stub = sinon.stub(subject, 'method', function(one, two) { 
    one(); 
    two(); 
});

subject.method(
    function() { console.log('callback 1'); }, 
    function() { console.log('callback 2'); });

Side note: This also gives the option for choosing if one or two should be called first.

like image 139
Emil Ingerslev Avatar answered Oct 17 '22 00:10

Emil Ingerslev


Why don't you skip sinon altogether?

var obj = { stubMe: function(cb1, cb2) {} };
var originalMethod = obj.stubMe;

obj.stubMe = function(cv1, cb2) { 
  //Whatever logic you wish
  cb1(); 
  cb2(); 
}; 

//Do your test

obj.stubMe = originalMethod; //Restore

This way you can even continue to use sinon's APIs, if you wish:

var stub = sinon.stub();
obj.stubMe = function(cb1, cb2) { 
  stub.apply(stub, arguments);
  //Rest of whatever logic you wanted here
};

obj.stubMe();
expect(stub.calledOnce()).to.be(true); //That would pass

What'd you think?

like image 38
Arseny Smoogly Avatar answered Oct 16 '22 23:10

Arseny Smoogly