Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling different callbacks for stub on firstcall and second call

Tags:

sinon

I'm looking for a way in sinon to call different functions in first and second call to the stub method.

Here is an example:

var func1 = function(connectionPolicy, requestOptions, callback) {
  callback({code: 403});
}

var func2 = function(connectionPolicy, requestOptions, callback) {
  callback(undefined);
}

var stub = sinon.stub();

// Something of this form
stub.onCall(0) = func1;
stub.onCall(1) = func2;

request.createRequestObjectStub = stub;

So that when request.createrequestObjectStub gets called internally(when calling a public API), I see this behavior.

  • Sinon version: 1.17.4
  • Environment: Node JS
like image 880
Rajesh Nagpal Avatar asked Jun 03 '16 15:06

Rajesh Nagpal


People also ask

How does Sinon stub work?

To stub a dependency (imported module) of a module under test you have to import it explicitly in your test and stub the desired method. For the stubbing to work, the stubbed method cannot be destructured, neither in the module under test nor in the test.

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 do I stub an object in Sinon?

If you need to check that a certain value is set before a function is called, you can use the third parameter of stub to insert an assertion into the stub: var object = { }; var expectedValue = 'something'; var func = sinon. stub(example, 'func', function() { assert. equal(object.


4 Answers

The only way I found to do what you want (with onCall(index) and an anonymous stub) is with bind JS Function.

This would be:

stub.onCall(0).returns(func1.bind()());
stub.onCall(1).returns(func2.bind()());

If you use stub.onCall(0).returns(func1()); the function func1 is executed when defining that onCall, that is why you need the .bind.

Anyway, you have other options, like returning a value directly with .onCall(index).returns(anObject); or defining a counter that is incremented each time your stubbed method is called (this way you know in which n-call you are and you can return different values).

For these three approaches, you can see the following fiddle with examples: https://jsfiddle.net/elbecita/jhvvv1h1/

like image 136
elbecita Avatar answered Oct 11 '22 12:10

elbecita


onCall worked for me. my code looks like:

const stubFnc = sinon.stub(myObject, "myFunction");
stubFnc.onCall(0).returns(mockObject1);
stubFnc.onCall(1).returns(mockObject2);
like image 34
titiu7 Avatar answered Oct 11 '22 12:10

titiu7


This is an old thread, but atleast as of Sinon 1.8, a more efficient way to solve this would be chaining sinon.onCall(arg) with callsFake().

So, in your use-case, you could do the following:

var func1 = function(connectionPolicy, requestOptions, callback) {
    callback({code: 403});
}
var func2 = function(connectionPolicy, requestOptions, callback) {
    callback(undefined);
}

var stub = sinon.stub();

// Solution

stub.onCall(0).callsFake(func1);
stub.onCall(1).callsFake(func2);

request.createRequestObjectStub = stub;
like image 5
coder_mz Avatar answered Oct 11 '22 14:10

coder_mz


You can use callsArg and callsArgWith from sinon.stub() to make sinon call the callbacks

Causes the stub to call the argument at the provided index as a callback function. stub.callsArg(0); causes the stub to call the first argument as a callback. source

Then you can do something like:

  myStub.onCall(0).callsArgWith(0, first);
  myStub.onCall(1).callsArgWith(0, second);
like image 1
Danny Sandi Avatar answered Oct 11 '22 14:10

Danny Sandi