1

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.

edhedges
  • 2,722
  • 2
  • 28
  • 61
  • @A.Wolff I can't get the code inside my `.done` and `.fail` callback to execute. The description also makes it clear :) – edhedges Dec 10 '13 at 14:02
  • are callbacks at least fired? Any error in console (client or server)? – A. Wolff Dec 10 '13 at 14:03
  • @A.Wolff The callback aren't fired. I'm not making real AJAX requests I'm trying to mock them, but at the same time I want to be able to execute the callbacks. – edhedges Dec 10 '13 at 14:07
  • so $.post() is not $.post(). What is $.post()? Are you returning any deferred object? – A. Wolff Dec 10 '13 at 14:10
  • @A.Wolff $.post is still jQuery $.post, but I've tried multiple ways of mocking up genericAddRowPost since it's the function that get's called and has the `.done` and `.fail` attached to it. – edhedges Dec 10 '13 at 14:24

2 Answers2

1

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
    });
});
Jason
  • 1,879
  • 16
  • 19
  • I'll try this out at work and be back to accept if it works. Are there example in the jasmine docs about this kind of stuff? – edhedges Dec 15 '13 at 19:24
  • 1
    I believe I learned about it on the Jasmine site. Here is a direct link to the Spies section (http://pivotal.github.io/jasmine/#section-Spies). – Jason Dec 16 '13 at 12:52
  • I can't get this to work... I get an error saying that `TypeError: Cannot call method 'done' of undefined`. Any ideas? – edhedges Dec 16 '13 at 19:52
0

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.

edhedges
  • 2,722
  • 2
  • 28
  • 61