1

I have a function which calls out for JSON and then in the success function makes some changes to the DOM. I'm trying to use the mock-ajax library in my Jasmine tests to avoid having to expose the various private functions for mocking.

Even though when stepping through the test the request.response is set the onSuccess method is never called.

My tests:

 describe('the table loader', function () {
        var request;

        beforeEach(function() {
            //html with a loader div, an output div and a transit and dwell template
            setFixtures('<div class="loader"></div><div class="row"><div id="output" class="col-xs-12"></div></div><script id="thingTemplate" type="text/x-handlebars">{{snip}}</script>');
            expect($('.loader')).toBeVisible();

            //start ajax call
            window.dashboards.thing.display({
                loaderId: '.loader',
                templateId: '#thingTemplate',
                templateOutletId: '#output',
                dataUrl: '/my/fake/url'
            });
            //catch the ajax request
            request = mostRecentAjaxRequest();
        });

        describe('on success', function () {
            beforeEach(function() {
                //populate the response
                request.response({
                    status: 200,
                    responseText: "{rowItem: [{},{},{}]}"
                });
            });

            it('should hide the loader', function () {
                //thing should now receive that JSON and act accordingly
                expect($('.loader')).not.toBeVisible();
            });
        });
    });

and my code:

(function (dashboards, $) {
    dashboards.thing = dashboards.thing || {};

    var compileTable = function(templateId, jsonContext) {
        var source = $(templateId).html();
        var template = Handlebars.compile(source);
        var context = jsonContext;
        return template(context);
    };

    var getDashboardData = function(options) {
        $.getJSON(
            options.dataUrl,
            function (data) {
                processDashboardData(options, data);
            }
        ).fail(function (jqxhr, textStatus, error) {
            console.log('error downloading dashboard data');
            console.log(textStatus + ': ' + error);
        }).always(function() {
            console.log('complete');
        });
    };

    var processDashboardData = function (options, data) {
        $(options.loaderId).hide();
        $(options.templateOutletId).html(compileTable(options.templateId, data));
    };

    dashboards.thing.display = function (options) {
        getDashboardData(options);
    };
}(
    window.dashboards = window.dashboards || {},
    jQuery
));

None of the deferred functions (success, error, and always) are being called.

Edit

based on @gregg's answer below (and he's right I didn't include the UseMock call in the example code) this feels like a versions issue. As even with that call included this still isn't working for me.

I've added a runnable example on github

Paul D'Ambra
  • 7,629
  • 3
  • 51
  • 96

3 Answers3

1

You need to make sure to install the ajax mock with jasmine.Ajax.useMock() before you actually make the call or jasmine-ajax won't have taken over the XHR object and you'll be making real requests. Once I did that against your sample code, it looks like the responseText you're sending isn't JSON parsable and jQuery blows up. But I was still seeing the 'complete' message logged in my console.

Gregg
  • 2,628
  • 1
  • 22
  • 27
  • AH! good to know I'm not completely crazy. Yep, I'd stripped out the useMock call by accident when making the example code. But it still doesn't run for me. I've added an example to GitHub. Could you take a look and see whether there are differences in versions of libraries we're using? Thanks! Paul – Paul D'Ambra Jan 27 '14 at 07:28
1

So, as of 29th Jan 2014, the download link in the Readme for mock-ajax on Github in the 1.3.1 tag doesn't point to the correct version of the file.

Manually downloading the mock-ajax file from the lib folder of the tag does work.

In other words for the 1.3.1 tagged release don't download from the readme link download from the tag lib folder directly

Paul D'Ambra
  • 7,629
  • 3
  • 51
  • 96
0

It's possible that the format of the data returned by your ajax call and jasmine's is different -- I believe that would throw an exception that wouldn't be recoverable, hence the reason none of your callback functions are running.

Newer versions of jasmine-ajax also use request.respondWith, and it's also of note (although I think jQuery handles this), that Jasmine doesn't have XMLHttpRequest.Done defined, so if you use vanilla JS you have to handle this case yourself. Lastly I use jasmine.Ajax.install() and not jasmine.Ajax.useMock().

Whew -- it's hard to know what exactly to do because Jasmine has such poor documentation for older versions and there are so many inconsistencies across them.

Kyle Chadha
  • 3,741
  • 2
  • 33
  • 42