Mocking Ajax with the JQuery Mockjax Library

Unit testing your JavaScript code to ensure everything works according to plan is a very important and tricky business. Properly testing code bits can save you a lot of time and money. This article focuses not on the general topic of unit testing JavaScript, but more specifically unit testing JQuery Ajax functions.

HTML File for the Test.
<!DOCTYPE HTML>
<html>
    <head>
        <link rel="stylesheet" href="lib/qunit.css" type="text/css" media="screen" />
        <script src="lib/qunit.js"></script>
        <script src="lib/jquery-1.7.js"></script>
        <script src="lib/json2.js"></script>
        <script src="lib/jquery.mockjax.js"></script>
        <script src="mockjax.js"></script>
        <title>MockJax Tests - </title>
      </head>
    <body>
        <h1 id="qunit-header">
            MockJax
        </h1>
        <h2 id="qunit-banner"></h2>
        <h2 id="qunit-userAgent"></h2>
        <ol id="qunit-tests"></ol>
    </body>
</html>


/**
 * User: ferron
 * Date: 1/4/12
 * Time: 8:52 PM
 */

var mockjaxDefaults = $.extend({}, $.mockjaxSettings);

var sampleJSON = '{"title":"Rope and Wood","url":"/music/jazz.mp3"}';

function noErrorCallbackExpected() {
    ok( false, 'Error callback executed');
}

// Speed up our tests
$.mockjaxSettings.responseTime = 0;

module('Ajax Mock');
asyncTest('Intercept and responseText (sub-ajax request)', function() {
    $.mockjax({
        url: '/tracks',
        responseText : sampleJSON
    });

    $.ajax({
        url: '/tracks',
        dataType: 'json',
        success: function(data) {
            ok(data && data.title, 'ResponseText request succeeded');
        },
        error: noErrorCallbackExpected,
        complete: function() {
            start();
        }
    });

    $.mockjaxClear();
});

asyncTest('Read repsonse text', function() {
    $.mockjax({
        url: '/tracks',
        responseText : sampleJSON
    });

    $.ajax({
        url: '/tracks',
        dataType: 'json',
        success: function(data) {
            equal('Rope and Wood',data.title, 'Title successful retrieved from JSON Object');
        },
        error: noErrorCallbackExpected,
        complete: function() {
            start();
        }
    });

    $.mockjaxClear();
});

The above example show the $.mockajax method being called before the $.ajax, here configurations and expectations are set. The first thing to not is the url ‘/track’ (mockAjax intercepts all ajax request to this url returning the expectation set by the mocked object) and responseText (The string that should be returned when the mock object is called).

NB: An issue I found with specifying a file (e.g response.json) is that it causes origin issues. To alleviate this problem the expected JSON was minified with JSMIN and placed in a variable called sampleJSON. After the mock has been setup, the normal Ajax flow is performed, specifying the same url that is in the mock url (This need to be the same). The data is then processed like normal.
After the Ajax method is complete the $.mockjaxClear method is called to teardown the mock that was previously created



Using Mockjax to stub Ajax calls

/**
 * User: ferron
 * Date: 1/4/12
 * Time: 8:52 PM
 */


var sampleJSON ='[{"name":"ben","clicks":"38"},{"name":"des","clicks":"45"},{"name":"benny","clicks":"46"},{"name":"unknown","clicks":"46"},{"name":"grumpy","clicks":"48"}]';


$.mockjax({
    url: '/scores',
    responseText : sampleJSON
});

$.ajax({
    url: '/scores',
    dataType: 'json',
    success: function(data) {
        if (data) { //check if any data is returned
            $.each(data, function (key, val) {
                $("#tbBody").append('<tr>' +
                    '<td><i>' + val.name + '</i></td>' +
                    '<td>' + val.clicks + '</td>' +
                    '</tr>');
            });
        }
        else {
            console.log("Aw Snap! : Something went wrong loading the articles");
        }
    },
    error: function() {
        console.log('Error loading data');
    },
    complete: function() {
        $.mockjaxClear();
    }
});


In the example above I have an ajax method that will retrieve player scores for a game from the server and append it to a table for display. The server is not yet created, so I’ve created a JSON representation of the output (sampleJSON) which is mocked with the library (mockjax). Upon called the url ‘/score’ the responseText method will return the sample JSON without changing the implementation. After the backend development is complete, the mock can be deleted and the link modified (if it needs to) without affecting the flow of the application.

Mockjax has truly help to speed up development by allowing web developers to not be altered by slow development or design timelines. Data can be stubbed until it’s fully implemented.


NB: Adding the following settings above the $.mockjax implementation will speed up rendering.
var mockjaxDefaults = $.extend({}, $.mockjaxSettings);
// Speed up our tests
$.mockjaxSettings.responseTime = 0;


Link to download examples found above: http://www.mediafire.com/?iwb37u6u0f5ukeb

Comments


  1. nice article.thank you for sharing useful post.
    web programming tutorial
    welookups

    ReplyDelete

Post a Comment

Popular posts from this blog

JavaScript Module Pattern: 2 Forms

Pseudo-Random UUID Generation with mask support