I have a function I am stubbing that gets called with multiple arguments. I want to check just the first argument. The rest are callback function, so I want to leave them alone. Thus, I might have the following 2 calls, using ajax as an example:
method.get = sinon.stub(); method.get(25,function(){/* success callback */},function(){/* error callback */}); method.get(10,function(){/* success callback */},function(){/* error callback */});
I cannot use method.get.calls...
because then it doesn't differentiate between the first one get(25)
and the second get(10)
. But if I use method.get.withArgs(25).calls...
then it does not match either, because withArgs()
matches all arguments, which this does not (and never could, with callbacks like that).
How do I get sinon stubs to check and set responses based on just the 1st arg?
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.
Sinon replaces the whole request module (or part of it) during the test execution, making the stub available via require('request') and then restore it after the tests are finished? require('request') will return the same (object) reference, that was created inside the "request" module, every time it's called.
var stub = sinon. The original function can be restored by calling object. method. restore(); (or stub. restore(); ).
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.
https://sinonjs.org/releases/latest/matchers/#sinonmatchany
You can use sinon.match.any:
method.get.withArgs(25, sinon.match.any, sinon.match.any);
withArgs
can be used to match some but not all the arguments.
Specifically, method.get.withArgs(25)
will check just the first argument.
This is incorrect:
withArgs()
matches all arguments
When withArgs
is called it remembers the arguments it was passed here as matchingArguments
.
Then when the stub
is called it gets all matching fakes here.
matchingFakes
is called without a second parameter so it returns all fakes that have matchingArguments
that match the arguments passed to the stub
starting at index 0 up to the length of matchingArguments
. This means that a fake will match when its matchingArguments
match the beginning of the arguments passed even if there are additional arguments.
Any matching fakes are then sorted by matchingArguments.length
and the one that matches the most arguments is the one that is invoked.
The following test confirms this behavior and passes with sinon
version 1.1.0
from 7 years ago, version 1.14.0
from the time this question was asked, and the current version 6.3.5
:
import * as sinon from 'sinon'; test('withArgs', () => { const stub = sinon.stub(); stub.withArgs(25).returns('first arg is 25!'); stub.returns('default response'); expect(stub(25)).toBe('first arg is 25!'); // SUCCESS expect(stub(25, function () { }, function () { })).toBe('first arg is 25!'); // SUCCESS expect(stub(10, function () { }, function () { })).toBe('default response'); // SUCCESS });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With