Aaron Ramirez
Aaron Ramirez

Reputation: 268

Sinon.js, QUnit, and Jquery. Attempting to verify posted data through FakeXMLHttpRequest

I have the following QUnit test case, which is attempting to verify the posted data sent through a JQuery ajax request:

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

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

    var callback = sinon.spy();
    var mockData = {mockData: "dummy content"}

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

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

});

The JSON.parse fails, because the request body is formatted as: mockdata=dummy+content

Because of how the data is encoded (spaces replaced with the + symbol), makes decoding the content, and subsequently making it JSON parseable very difficult.

The end goal is to dynamically verify the request data, using the fake XHR object. I prefer this over mocking the jQuery post or ajax methods. Since if I switch between implementations for sending AJAX requests, I don't want my unit tests to fail.

Has anyone had any luck with this?

References:

Demo of the above code: http://jsfiddle.net/ZGrTK/66/

An article that demonstrated what I was trying to achieve: http://philfreo.com/blog/how-to-unit-test-ajax-requests-with-qunit-and-sinon-js/

(The code fails to work for me. Something to deal with backbone.js I suspect. I have no experience with that framework though.)

Upvotes: 2

Views: 903

Answers (1)

psquared
psquared

Reputation: 1129

A couple comments on your test:

  • jQuery ajax() documentation says that if the data parameter isn't a string, it will be converted to a query string using $.param(). You could avoid that conversion by passing a string.
  • The last assert compares [Object].mockData to a variable named mockData. I'm guessing that's just a typo.

Here's a slightly modified test (JSFiddle) that passes:

test("ajax tests", function () {
    var xhr = sinon.useFakeXMLHttpRequest(),
        requests = [],
        mockURI = '/some/article',
        mockData = {
            someProperty: "dummy content"
        };

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

    $.ajax(mockURI, {
        data: JSON.stringify(mockData),
        type: 'POST'
    });

    equal(requests.length, 1);
    equal(requests[0].url, mockURI);
    equal(JSON.parse(requests[0].requestBody).someProperty, mockData.someProperty);

    xhr.restore();
});

As for the article, I didn't really study the code, but it seems to work: JSFiddle.

Upvotes: 2

Related Questions