Unit Testing Ajax with Sinon.js and QUnit

I’ve done unit testing with JavaScript using QUnit, but I’ve never tried writing unit tests for Ajax. I recently learned about Sinon.js however, and that has taken unit testing in JavaScript to a whole new level for me. By default, Sinon.js doesn’t work with QUnit, but fortunately you can add another script to make it work.

While attempting to write unit tests for Ajax, I had trouble finding good information. I actually found the solution in the Sinon.js docs. The secret to unit testing Ajax is not spies, stubs or mocks that are available in Sinon.js but the Fake XMLHttpRequest. This allows you to test Ajax calls and callbacks without making actual Ajax requests. The following test passes in QUnit.

test("ajax tests", function () {
    var xhr = sinon.useFakeXMLHttpRequest();
    var requests = sinon.requests = [];

    xhr.onCreate = function (request) {
        requests.push(request);
    };

    var callback = sinon.spy();

    $.ajax('/some/article', { success: callback });

    equal(sinon.requests.length, 1);
    equal(sinon.requests[0].url, "/some/article");

    requests[0].respond(200, { "Content-Type": "application/json" }, 
'[]');

    ok(callback.called);
});

You can see the code working here in jsfiddle. As you can see, the Ajax request was called with the right url. With the respond method, we were able to make our fake Ajax call return a 200 code so that the callback will be run as well. The trick is calling the respond method every time a request is sent. You just have to increment the number of the array item.

Here I am only returning an empty array because I couldn’t get the code to work in jsfiddle, but you can control what data is returned by the Ajax call, as well.

That’s it. I didn’t go into detail here about how QUnit or Sinon.js work, so you will need to check out their respective documentation if you are wondering about that. Unit testing Ajax is just one of the benefits of Sinon.js. If you aren’t already using it, I recommend that you do.