Avius
Avius

Reputation: 6244

Sinon stub withExactArgs?

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

Answers (1)

Brian Adams
Brian Adams

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

Related Questions