Reputation: 6244
Sinon mocks have a method withExactArgs, which asserts the number of arguments passed to the method in question. Is there a way to have this behaviour using stubs?
Right now they seem to work like this:
const methodStub = stub();
methodStub.withArgs().returns(1);
console.log(methodStub()); // prints 1
console.log(methodStub({})); // also prints 1
I would like to have an exact argument match. I have looked into adding a custom behaviour to sinon, which didn't work out. I don't really know what to try next.
I am aware that I can check the arguments after the calls have been made, but I feel like the cleanliness of the test written that way does not fare.
Also, this reasonably well-received post on SO has me very confused: Can sinon stub withArgs match some but not all arguments. Quote:
if I use method.get.withArgs(25).calls... then it does not match either, because withArgs() matches all arguments
I seem to be observing the complete opposite with Sinon v6, exactly the behaviour that the OP was looking for...
Upvotes: 2
Views: 1503
Reputation: 45780
This statement from the linked question is incorrect:
withArgs()
matches all arguments
withArgs
does not match all arguments. I've added an answer with details.
withExactArgs
for a stub
has been discussed but never implemented.
So yes, checking the arguments after the calls have been made, using callsFake
with a custom function, adding custom behavior, or using a mock
instead of a stub
are the current options in sinon
for asserting that a method was called with exact args.
As an example, the stub from the question looks like it should only return 1
if it is called with no arguments which can be done using callsFake
:
test('stub exact args', () => {
const stub = sinon.stub();
stub.callsFake((...args) => {
if (args.length === 0) {
return 1;
}
return 'default response';
});
expect(stub()).toBe(1); // SUCCESS
expect(stub({})).toBe('default response'); // SUCCESS
});
Upvotes: 1