Search code examples
unit-testingqunitsinon

Asserting a specific stub call was made with the required arguments using sinon


Let's say you are testing a function that will call a dependency multiple times with different arguments:

var sut = {
    ImportantFunction: function(dependency){
        dependency("a", 1);
        dependency("b", 2);
    }
};

Using QUnit + Sinon and assuming the order of the calls is not important, I could write the following test that makes sure the function calls the dependency as expected:

test("dependency was called as expected", function () {
    var dependencyStub = sinon.stub();

    sut.ImportantFunction(dependencyStub);

    ok(dependencyStub.calledTwice, "dependency was called twice");            
    sinon.assert.calledWith(dependencyStub, "a", 1);
    sinon.assert.calledWith(dependencyStub, "b", 2);
});

But what if the order is important and I want the test to take it into account? What is the best way to write such a test using QUnit+Sinon?

I have used the following approach, but I am losing the descriptive failure message provided by sinon assertions (which shows expected and actual values). For this I have just manually added some descriptive message, but it is not as useful as having a failure message with the expected and actual values (and has to be manually maintained).

ok(dependencyStub.firstCall.calledWith("a", 1), "dependency called with expected args 'a', 1");
ok(dependencyStub.secondCall.calledWith("b", 2), "dependency called with expected args 'b', 2");

Is there a way of using an assertion like sinon.assert.calledWith for a particular call like the first or second call?

Sample setup in this fiddle


Solution

  • You can use sinon.assert.callOrder(spy1, spy2, ...), or spy1.calledBefore(spy2) or spy2.calledAfter(spy1).

    These can also be used with the result of spy.calledWith(...), e.g. sinon.assert.callOrder(spy.withArgs('a'), spy.withArgs('b')).