Using Pretender to mock HTTP requests in a Ember/Rails app

We're developing LearningSpaces in Ember, with a Rails backend. We'll use this blog to share our experiences. Any questions? Hit us up on Twitter.

When testing your Ember frontend you don't want to be making actual requests to your backend. Using Embers FixtureAdapter gets you a bit further, but after a while the differences between your actual backend and the fixture adapter can trip you up a bit.

Here's where the Pretender library comes in handy! Pretender allows you to mock any HTTP requests you app makes and return a given response. Pretender is a JS library and so there isn't a gem readily available. Luckily there is a Bower package that we can pull in using rails-assets.org:

# Gemfile
source "https://rubygems.org"  
source 'https://rails-assets.org'

ruby "2.1.0"  
# ...

group :test do  
  # ...
  gem "rails-assets-pretender"
end  

Include Pretender and its dependencies in your spec_helper.js file:

# spec/javascripts/spec_helper.js
//= require route-recognizer
//= require FakeXMLHttpRequest
//= require pretender

And you can now stub HTTP requests in your specs:

var server;  
module('Integration: Comment on Chapter', {  
  setup: function () {
    server = new Pretender(function () {
      this.get('/api/v1/learning_spaces/1', function (request) {
        return MockResponse.ok(Fixtures.LearningSpace);
      });
    });
  },

  teardown: function () {
    server.shutdown();
  }
});

The MockResponse.ok that we're returning is a simple helper wrapper around Pretenders responses:

var MockResponse = {  
  ok: function (data) {
    return [200, { 'Content-Type': 'application/json' }, JSON.stringify(data)];
  },
};

We've tucked away our mock response data in a Fixtures object to keep our tests clean, but you can return any valid JSON you need.

Now any request you make to /api/v1/learning_spaces/1 will be picked up by Pretender, no actual requests will be made and the JSON that you specified will be returned.

And that's it! Happy testing!