Quickie: Sinon.JS withArgs not working


From time to time we run into a bit of an edge case when using Sinon.JS withArgs() - it seemingly does not work. Sinon 1.15.4 ignores withArgs() validation if creating the stub inline. This may cause failing tests to pass.

This will not work as expected:

var inline = sinon.stub().withArgs(1).returns(true);

console.log(inline(1)); // true
console.log(inline(2)); // true // ???

This will work:

var preInit = sinon.stub();
preInit.withArgs(1).returns(true);

console.log(preInit(1)); // true
console.log(preInit(2)); // undefined // great!

The problem here is that, while fluent, Sinon doesn’t quite work the way you would expect it to. You can chain the calls, which gives the misleading impression that it remembers intermediate steps.

The fact that each step returns a seemingly simple stub only increases the confusion:

console.log(sinon.stub().withArgs(1).returns(1)); // function stub() {...}
console.log(sinon.stub()); // function stub() {...}

The last returns() call gives a stub that always returns whatever it’s argument was and disregards previous definitions:

var typeDetector = sinon.stub()
  .withArgs(sinon.match.string).returns('I am a string') //ignored
  .withArgs(sinon.match.number).returns('I am a number');

typeDetector('definitely a string') // returns 'I am a number' :(

Here’s a Plunker replicating it. Open the console to see the behavior.

Seems like it won’t be fixed, so just something to keep in mind.