How to test and get full code coverage on ajax request and it's done and fail callbacks of jQuery ajax request using Jasmine and Blanket.js?

753 views Asked by At

So I have something like this:

var Utils = {};

Utils.genericAddRowPost = function(url) {
    return $.post(url);
};

Utils.genericAddRow = function(dataSource, url) {
    genericAddRowPost(url).done(function(data, textStatus, jqXHR) {
        // add on to dataSource and other stuff
    }).fail(function (jqXHR, textStatus, errorThrown) {
        //handle error
    });
};

I am attempting to test and achieve 100% code coverage using jasmine and blanket, but I can't seem to be able to mock/execute the done and fail handlers. Any help would be greatly appreciated. I would prefer not to have to restructure any of the code posted if possible.

2

There are 2 answers

0
edhedges On BEST ANSWER

So here is what I did:

it('Verify Utils.genericAddRow', function () {
    var wasSuccessful = false;

    mockObj = {
        data: ko.observableArray([{}])
    };

    // spy on genericAddRowPost that is called inside this test function
    spyOn(Utils, "genericAddRowPost").andReturn({
        done: function (callback) {
            callback({});
            wasSuccessful = true;
            return this;
        },
        fail: function (callback) {
            return this;
        }
    });

    // Call our test function and make first set of expectations
    Utils.genericAddRow(mockObj, 'fakeUrl');
    expect(Utils.genericAddRowPost).toHaveBeenCalledWith('fakeUrl');
    expect(wasSuccessful).toBeTruthy();

    // Override original spy implementations
    Utils.genericAddRowPost().done = function (callback) {
        return this;
    };
    Utils.genericAddRowPost().fail = function(callback) {
        callback(null, null, 'testError');
        wasSuccessful = false;
        return this;
    };

    // Call our test function and make second set of expectations
    Utils.genericAddRow(mockObj, 'anotherFakeUrl');
    expect(Utils.genericAddRowPost).toHaveBeenCalledWith('anotherFakeUrl');
    expect(wasSuccessful).toBeFalsy();
});

I will edit my question to reflect that genericAddRow and genericAddRowPost are both functions that live on a Utils object literal.

3
Jason On

Using Jasmine, you should be able to spy on your ajax calls and simulate success and failure conditions.

Something like this:

describe("my tests", function () {

    beforeEach(function () {
        spyOn(jQuery, "ajax");
    });

    it("should handle success", function () {

        genericAddRow(a, b);

        // call the success callback
        $.ajax.mostRecentCall.args[1].success(data, textStatus, jqXHR);

        // do your tests here
    });

    it("should handle failure", function () {

        genericAddRow(a, b);

        // call the success callback
        $.ajax.mostRecentCall.args[1].error(jqXHR, textStatus, errorThrown);

        // do your tests here
    });
});