Search code examples
sinon

Doing CallOrder of Fake on itself with argument validation


How do i do a call order verification of a fake with argument validation in sinon.js? It is the same fake which is called multiple times with different arguments... something like below

        let someFake = sinon.fake();
        someFake(1);
        someFake(2);
        someFake(3);
        sinon.assert.callOrder(someFake.calledWith(1), someFake.calledWith(2), 
        someFake.calledWith(3));

Solution

  • You are essentially using the wrong API for the job, so it's no wonder you are not getting the expected results :) If you look at the docs for callOrder you will see that the signature is using spy1, spy2, .., which indicates that it is meant to be used by more than one spy. A fake is implementation wise also a Spy, so all bits of the Spy API also applies to a Fake. From the docs:

    The created fake Function, with or without behavior has the same API as a sinon.spy

    A sidenode, that is a bit confusing, is that the docs often use the term "fake" to apply to any fake object or function, not functions created using the sinon.fake API specifically, although, that should not be an issue in this particular case.

    With regards to your original question, the Spy API has got you covered since Sinon 1.0 here. You use getCall(n) to return the nth call. There are lots of interactive examples in the docs for this, but essentially you just do this:

    // dumbed down version of https://runkit.com/fatso83/stackoverflow-66192966
    
    const fake = sinon.fake();
    fake(1);
    fake(20);
    fake(300);
    
    sinon.assert.calledThrice(fake);       
    assertEquals(1, fake.getCall(0).args[0])
    assertEquals(20, fake.secondCall.args[0])
    assertEquals(300, fake.lastCall.args[0])
    
    function assertEquals(arg1,arg2){
      if(arg1 !== arg2) { 
         throw new Error(`Expected ${arg1} to equal ${arg2}`); 
      }
      console.log(`${arg1} equal ${arg2}: OK`)
    }
    <script src="https://cdn.jsdelivr.net/npm/sinon@latest/pkg/sinon.js"></script>