The No Nonsense Guide to Test Driven Development With Ember.js on Rails

Written by

This is a no non-sense, no steps skipped guide to getting an Ember.js app to a place where you can do unit test driven development. This guide picks up where The No non-sense Guide To Ember.js on Rails left off. It assumes you have a rails app running with Ember.js installed and working.

Before we get started, you might also find The no nonsense guide to Ember JS on Rails

We’ll be using Jasmine for writing tests. Jasmine is a framework for writing specs that looks quite a bit like rspec. It’s easy to get up to speed in an afternoon writing Jasmine and it produces specs that are easy to write and easy to read. I think it’s enjoyable to work with.

To start, we’ll install jasmine in the app by adding a Gem called jasminerice:

group :development, :test do  
    gem "jasminerice", :git => 'https://github.com/bradphelan/jasminerice.git'  
end  

Adding jasminerice

Jasminerice adds jasmine to the app and mounts the spec runner at http://localhost:3000/jasmine. It lets you use the asset pipeline to include your complete application into the test suite. This is part of what makes testing with Jasmine so painless.

After you’ve installed jasminerice, it needs to be bootstraped to get the files to the right place.

`rails g jasminerice:install`

Installing jasminerice

If you fire up the app right now and navigate to localhost:3000/jasmine you’ll encounter an error. Jasminerice ships with an example spec, but it doesn’t work out of the box. It’s worth taking a look at the example spec if you’re curious, otherwise you can fix this by removing the sample: rm spec/javascripts/example_spec.js.coffee. At this point you have jasmine installed and running and your ready to begin test driven development.

Jasminerice error

The next step is to include our application into the jasmine testing environment. This is where the real power of jasminerice shines through. With one line, in spec.js.coffee, we can include our whole ember application. Just above require_tree ./ add require application.

Require application

Test Driving A Small feature

To help get into the flow of test driven development with Jasmine, let’s implement a small feature. We’ll create a person model with a first name and last name and then test drive writing a fullName method on the Ember model.

First, let’s scaffold out a person with a firstName and lastName:

rails g scaffold Person first_name:string last_name:string

Scaffolding the person

Thanks to some cleverness in the ember rails gem, this also creates an ember model and views. Next we need to add our spec, create a new file in touch spec/javascripts/models/person_spec.js and add a spec that looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
describe("Person", function() {
  beforeEach(function() {
    Ember.testing = true;
  });

  describe("Full Name", function() {
    it('builds the full name from firstName and lastName', function() {
      Ember.run(function() {
        person = App.Person.createRecord({firstName: 'Nick', lastName: 'Rowe'});
        expect(person.get('fullName')).toEqual('Nick Rowe');
      });
    });
  });
});

Jasmine spec

This spec is fairly readable but there are two interesting pieces that you’re probably wondering about. The first is Ember.testing = true. Normally when Ember is running it has a runloop. This runloop causes all kinds of things to happen, however during testing we want to control the world as much as possible. Setting Ember.testing tells ember to halt the run loop. The next interesting piece is Ember.run. This is related to the Ember testing setting. We need the run loop to make one run all the way through to complete our test.

When you run the test you should now see something like this:

One failing jasmine test

We are now ready to implement the feature. In app/assets/javascripts/models/person.js let’s add a new function for fullName:

1
2
3
  fullName: function() {
    return this.get('firstName') + ' ' + this.get('lastName');
  }.property('firstName', 'lastName'),

Now when the tests are run again, we should see a screen like this:

One passing jasmine test

That’s all there is to writing and running unit style tests for Ember.js using jasmine.


ember,, ember-for-rails,, rails

Comments or Questions? Contact Nick @nixterrimus on twitter.

Nick is a software engineer, geek, web enthusaist, open source contributor, home automation tinkerer, ocean admirer and all around general optimist living in San Francisco. Want to get in touch about professional matters? Nick Rowe is also available on LinkedIn.