Mocking jQuery AJAX with AmplifyJS Request
1 min read
In my opinion the most powerful part of the AmplifyJS library is the request component. The documentation is nice, but I wanted to highlight the mocking piece in particular because it is very powerful, but is easy to miss.

Being able to separate what a request looks like from the actual request itself proves to be a very effective way to develop. It protects yourself from future changes to the request/response handshake and also makes it really easy to mock responses for unit testing or for rapid prototypes.

Standard Request Define and Request Usage

The following snippet of code defines what a request should look like that communicates to twitter to get someone's recent tweets.

// Define what a getTweets request looks like... url, dataType, etc
amplify.request.define( "getTweets", "ajax", {
url: "{userName}.json",
dataType: "jsonp",
type: "GET"
view raw request.define.js hosted with ❤ by GitHub
When you want to use the definition above you just reference the resourceId that you provided ("getTweets"), you pass any data you want to pass along, and give a callback function that will be invoked when the response comes back.

// Request "getTweets" passing in necessary data used in URL substitution
resourceId: "getTweets",
data: { userName: "elijahmanor", count: 25 },
success: function( data, status ) {
console.log( data, status );
error: function( data, status) {
console.log( data, status )
view raw request.js hosted with ❤ by GitHub

Easily Mocking the Request

If for some reason you don't have internet access, the service you are using is unstable, or you just need to unit test some code then you can mock the response by redefining the resourceId and using a function as the 2nd parameter that will be used for the mock.

// Redefine the getTweets request with hard-coded data
amplify.request.define( "getTweets", function ( settings ) {
{ id: 0, text: "Test Tweet 1", user: { name: "User 1" }, favorited: false, retweet_count: 0, created_at: "Mon Apr 11 8:00:00 +0000 2012" },
{ id: 1, text: "Test Tweet 2", user: { name: "User 2" }, favorited: true, retweet_count: 1, created_at: "Mon Apr 11 9:00:00 +0000 2012" },
{ id: 2, text: "Test Tweet 3", user: { name: "User 3" }, favorited: false, retweet_count: 2, created_at: "Mon Apr 11 10:00:00 +0000 2012" },
{ id: 3, text: "Test Tweet 4", user: { name: "User 4" }, favorited: true, retweet_count: 3, created_at: "Mon Apr 11 11:00:00 +0000 2012" },
{ id: 4, text: "Test Tweet 5", user: { name: "User 5" }, favorited: true, retweet_count: 4, created_at: "Mon Apr 11 12:00:00 +0000 2012" }
view raw request.mock.js hosted with ❤ by GitHub

Using mockJSON to Generate Randomized Data

If you are anything like me, then you are awful at making sample data. I end up with something like "Test 1", "Test 2", etc... which is laborious, looks silly, and doesn't really exercise your UI at all. If you want to semi-randomize your data for prototyping then using the mockJSON library can be helpful. The following code says to generate an array of 20 to 30 tweets that follow the format specified.

The mockJSON library, written by Menno van Slooten (@mennovanslooten), I am using has been beneficial to me when building prototypes when the backend is either unstable or not developed yet.

// Redefine getTweets request with semi-random prototype data using the mockJSON library
amplify.request.define( "getTweets", function ( settings ) {
var mockData = $.mockJSON.generateFromTemplate({
"tweets|20-30": [{
"id|+1": 0,
"text": "@LOREM_IPSUM",
"user": { "name": "@MALE_FIRST_NAME @LAST_NAME" },
"favorited|0-1": false,
"retweet_count|0-10": 0,
"created_at": "Mon Apr 11 @TIME_HH:@TIME_MM:@TIME_SS +0000 2012"
settings.success( mockData.tweets );
view raw request.mockjson.js hosted with ❤ by GitHub
The following screenshot is an example of what one of the above objects looks like after using mockJSON. As you can see, the object can almost pass as a legitimate tweet (minus the actual tweet.text). mockJSON allow you to create custom keywords to extend the native ones like @MALE_FIRST_NAME, so you could conceivably make a new keyword that can make a more believable tweet.text.

If you defined the same resourceId multiple times, then the last one defined wins. So, the following output is from the mocked version using mockJSON to semi-randomize the twitter response. Note: If I wanted to switch to the real twitter, I would just need to comment out my mocked versions.

I just scratched the surface of what you can do with AmplifyJS Request. It can support caching, decoders, dataMaps, custom request types, and more. Check out the documentation for more details.

Edit post on GitHub

Adding jQuery Deferred Support to AmplifyJS Request
Don't Initialize All the Things in jQuery.ready()