Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ThomasBurleson/1371926 to your computer and use it in GitHub Desktop.
Save ThomasBurleson/1371926 to your computer and use it in GitHub Desktop.
Simple jQuery (1.5+) AJAX Mocking (requires JSON, tested in jQuery 1.7))
// mock ajax
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
if ( /^\/?mock-ajax/.test( originalOptions.url ) ) {
// make new deferred and save any success/error handlers
var success = options.success,
error = options.error;
// kill off the old handlers
options.success = options.error = null;
var promise = $.Deferred( function(dfd) {
var echo = originalOptions.data.echo || {},
delay = originalOptions.data.delay || 50,
status = originalOptions.data.status || true;
// Use the Deferred to simulate success and error
dfd.done( function() {
success.apply( options, arguments );
})
.fail( function(a,b,c) {
error.apply( options, arguments );
});
// resolve the data
setTimeout( function() {
dfd[ status ? 'resolve' : 'reject' ]( echo, 'success', jqXHR );
}, delay );
// !! Abort out of this function, so the promise still gets returned via $.ajax
setTimeout(function(){
jqXHR.abort( 'success' );
}, 0);
}).promise( jqXHR ); // map these promise methods onto the jqXHR
}
});
$.ajax({
url: '/mock-ajax/390?thing=poop&pop[]=1&pop[]=2',
type: 'GET',
data: {
echo: 'gimme',
delay: 2000
},
success: function( data ) {
console.log( 'SUCCESS!' );
console.dir( data );
},
error: function(){
console.log( 'failed :/');
}
}).always( function(a,b,c) {
console.log( 'promise done', a,b,c );
});
/*!
* Simple jQuery (1.5+) AJAX Mocking - v0.1.0 - 11/16/2011
* http://benalman.com/
*
* Copyright (c) 2011 "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
$.each($.mockAjax.rules[dataType], 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!
done("200", "success", {status: response});
},
// 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) {
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, 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 = {};
}(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();
});
});
@ThomasBurleson
Copy link
Author

Mock testing becomes critical when running QUnit javascript test suites.

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