Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created November 16, 2011 20:24
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save cowboy/1371254 to your computer and use it in GitHub Desktop.
Save cowboy/1371254 to your computer and use it in GitHub Desktop.
Simple jQuery (1.5+) AJAX Mocking (requires JSON, tested in jQuery 1.7))
/*!
* Simple jQuery (1.5+) AJAX Mocking - v0.1.1 - 2012-08-17
* http://benalman.com/
*
* Copyright (c) 2012 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($) {
// Process all rules for a given AJAX request.
function processRules(options) {
// The dataType (eg. "json").
var dataType = options.dataType || '*';
// If a rule is matched, override the built-in transport.
var transport;
// Iterate over all specified rules for this dataType, defaulting to
// catch-all "*" rules if there are no dataType-specific rules.
var rules = $.mockAjax.rules[dataType] || $.mockAjax.rules['*'] || [];
$.each(rules, function(_, rule) {
// Test the AJAX request URL against this rule's regexp.
var matches = options.url.match(rule.re);
// If there was a match, override the default transport.
if (matches) {
transport = {
// Override the transport's send to immediately return a result.
send: function(_, done) {
// Get the response value.
var response = rule.response;
// If the response is a function, invoke it, passing in the matches
// array and the AJAX request options, and get its result.
if ($.isFunction(response)) {
response = response(matches, options);
}
// If the dataType is "json" or "jsonp" and not a string, serialize
// it into a valid JSON string. Note: requires JSON!
if (/^json/.test(dataType) && typeof response !== "string") {
response = window.JSON ? JSON.stringify(response) : String(response);
}
// Respond successfully!
var delay = $.mockAjax.options.delay;
setTimeout(function() {
done("200", "success", {status: response});
}, $.isFunction(delay) ? delay() : delay);
},
// Don't do anything on abort. Don't abort. Should this do anything?
abort: $.noop
};
// Don't process any other rules for this AJAX request.
return false;
}
});
return transport;
}
// Mock AJAX requests for a given dataType and map of rules.
$.mockAjax = function(dataType, userRules) {
if (arguments.length === 1) {
userRules = dataType;
dataType = '*';
}
var rules = $.mockAjax.rules[dataType];
// If no rules exist for this datatype, create a place to store them and
// register an ajax transport handler for that datatype.
if (!rules) {
rules = $.mockAjax.rules[dataType] = {};
$.ajaxTransport(dataType === '*' ? '+*' : dataType, processRules);
}
// For each user rule specified, add an entry into this dataType's rules
// object, overwriting any already-existing rule with the same pattern.
$.each(userRules, function(pattern, response) {
rules[pattern] = {
// Compile a matching regexp up-front to save processing later.
re: new RegExp("^" + pattern + "$"),
// Store the response value / function.
response: response
};
});
};
// Initialize an empty rules object.
$.mockAjax.rules = {};
// Options.
$.mockAjax.options = {
delay: function() { return Math.random() * 250 + 50; }
};
}(jQuery));
// Simulate your API.
$.mockAjax("json", {
"/user": {status: -1},
"/user/(\\d+)": function(matches) {
return {status: 1, user: "sample user " + matches[1]};
}
});
// Unit tests.
test("user tests", function() {
expect(5);
stop();
$.getJSON("/user", function(data) {
ok(data, "data is returned from the server");
equal(data.status, "-1", "no user specified, status should be -1");
start();
});
stop();
$.getJSON("/user/123", function(data) {
ok(data, "data is returned from the server");
equal(data.status, "1", "user found, status should be 1");
equal(data.user, "sample user 123", "user found, id should be 123");
start();
});
});
@cowboy
Copy link
Author

cowboy commented Nov 16, 2011

FWIW, I wrote this plugin in about half an hour for my 2011 jQuery Summit talk, Unit Testing with QUnit. It works, but is very basic. Based on examples found in the jQuery Extending AJAX documention.

I'll add more to it when I have the time.

Also, it might work with jQuery 1.5+ but it's only been tested in jQuery 1.7.

@michaelmior
Copy link

For another option, anyone who sees this may be interested in jQuery Mockjax.

@stevermeister
Copy link

thank you! exactly what I need now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment