TDD with Backbone and Rails 3.1

Written by mitro on December 8th 2011

Rails forced Test Driven Development from the very beginning and made it very easy (if you have never tried it, the Rails Guide on testing is a pretty good starting point).

However, TDD with Rails and Backbone is a different story since in that scenario Rails usually does nothing more than providing authentication and an API for your frontend - so even full test coverage on the Rails side will not assure a working application.

Things got even trickier with Rails 3.1 since all relevant files have to be loaded through the asset pipeline in order to use CoffeeScript instead of raw JavaScript.

This guide will help you set up an environment for practicing test driven Backbone development with Rails. It is written for Rails 3.1 and Backbone 0.5.

Create a new Rails application

You probably know how this works. I named the application "Blog" to keep things simple.

Install Backbone

Edit your Gemfile to install the backbone-rails gem (be careful as both rails-backbone and backbone-rails gems are available):

Gemfile gem 'rails-backbone'

Run bundle install.

Create Backbone's directory structure

rails generate backbone:install

This bootstraps Backbone inside your application and makes sure everything gets loaded via the asset pipeline. You also get generators for your Backbone objects.

Install Jasmine.js

Update your Gemfile to install the jasminerice gem:

Gemfile gem 'jasminrice'

This gem makes Jasmine.js available for the asset pipeline, includes a patched version of jasmine-jquery and provides a route to run your specs.

Install Sinon.js

For convenience I like to include Sinon.js for spying, mocking and stubbing. Since there is no gem available, you have to install it by hand.

This is quite easy since your application's vendor-directory is included in the asset pipeline. So grab a fresh version and save it as vendor/assets/javascripts/sinon.js.

Create directory structure for specs

The jasminerice gem expects your specs to be placed inside spec/javascripts, so go on and create the following directories and files:

spec
spec/javascripts
spec/javascripts/spec.js.coffee
spec/javascripts/spec.css.scss
spec/javascripts/fixtures

Edit spec.js.coffee

This file is responsible for loading all JavaScript-files needed for testing. Remember, it is loaded via the asset pipeline so all you have to do is include the whole directory:

#= require_tree ./

We want Sinon.js only to be included for testing so we include it here.

#= require sinon

Now all your specs will load and Sinon.js will be available, but your tests will not know anything about the code being tested. This is easy to fix because the rails-backbone gem already created application.js, which includes all files necessary for running your application. Since this file is also in the asset pipeline all you have to do is include it here:

#= require application

Your spec.js.coffee-file should now look like this:

#= require_tree ./
#= require sinon
#= require application

Try it out

Restart your Rails server, go to http://localhost:3000/jasmine and you should see Jasmine.js at work. Now all we need is a spec to run.

Create a spec

Create a spec for a Post model in spec/javascripts/post_spec.js.coffee (should be clear now why the application was named "Blog"):

describe 'Post', ->

  it 'loads correctly', ->
    post = new Blog.Models.Post
    expect(post.testValue).toEqual 'loaded'

Refresh your browser and watch the test fail. Now create the Post model in assets/javascripts/backbone/models/post.js.coffee:

class Blog.Models.Post extends Backbone.Model

  initialize: ->
    @testValue = 'loaded'

When you refresh your browser again, you should see the test pass. From now on, there is no excuse for not testing your Backbone/Rails applications.

Expect some hints on how to tackle some Backbone-specific TDD problems in one of the next posts.

Comments

Your comment

Your message

For now, please do not use any HTML tags.

Your name

Your website (optional)

Maybe you'll get a little extra traffic.