Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

Unit-Testing AngularJS in a Rails app using the Jasmine gem

Testing AngularJS applications is easy with Jasmine. If you look at the AngularJS docs, many of the code examples show a corresponding Jasmine spec.

One important part of AngularJS’s testing support is the included angular-mocks.js file. This file contains a module called NgMock that provides a set of fake services for things such as HTTP requests, in order to make them easier to unit test.

As soon as you include this file, the built-in services are overridden with the fake versions. So you should include this file in your Jasmine test environment, but not in your production code.

The Rails asset pipeline makes it easy to version-control and upgrade third party JS libraries such as AngularJS. For instance, there is a popular gem called angularjs-rails that includes all of the AngularJS source files.

Let’s say you have this in your Gemfile:

gem "angularjs-rails"

Whenever you run bundle update angularjs-rails, you will get the latest version of AngularJS in your application without any additional effort. And since angular-mocks.js is included in the gem, its version will also be upgraded in sync.

Unfortunately, up until now, it has been a bit difficult to include asset files from gems into your Jasmine environment using the official Jasmine gem.

Using the currently released version (2.0.1), there is no way to require files from the asset pipeline from code in your spec/javascripts directory. There are two workarounds to this problem, neither of which is completely satisfactory:

  • Copy the file from the gem into spec/javascripts/helpers so that it gets included into the Jasmine environment. You will need to remember to update this file when the gem is upgraded.
  • Make a file in your application’s assets, such as app/assets/angular_mocks.js, that requires angular-mocks.js, and include this file in your Jasmine environment, but not in your application. This is strange because you now have test-specific code mixed in with your production code. Also, it becomes easier to accidentally include the NgMock code using something like //= require_tree .

So we decided to improve the situation by changing the Jasmine gem code to add all of the Rails asset pipeline paths into the test environment. We made a pull request, and the code is now available in the latest HEAD version of Jasmine.

Here is a quick example on how you can start testing AngularJS in your application with the new asset pipeline support.

Installing AngularJS and Jasmine

First you need to include angularjs-rails and Jasmine, making sure Jasmine is pointed to HEAD. Then, run Jasmine’s install script.

# ./Gemfile
gem "angularjs-rails"
gem "jasmine", github: "pivotal/jasmine-gem"
$ bundle install
$ rails g jasmine:install

Including angular-mocks

After the install is done you should have Jasmine’s structure created under your ./spec/javascripts folder. Now you can create a spec helper file such as ./spec/javascripts/helpers/angular_helpers.js and include angular-mocks.

//= require angular-mocks

Running the tests

That’s all the setup you need to know. You can run your specs in the browser using the traditional rake jasmine and start TDDing your new AngularJS app.

For a complete example please refer to this sample app.

Happy TDDing!

Thanks to Vanessa Sant’Anna and David Dening for pairing with me on solving this issue and writing this blog post! And to Rajan Agaskar from the Jasmine team for quick feedback on our pull requests.

  1. Travis Grathwell says:

    We’re using the angularjs-rails gem as well, with the stock jasmine 2.0.1 gem, and all we had to do was change our jasmine.yml as follows:

    # src_files
    # Return an array of filepaths relative to src_dir to include before jasmine specs.
    # Default: []
    # EXAMPLE:
    # src_files:
    # – lib/source1.js
    # – lib/source2.js
    # – dist/**/*.js
    – assets/application.js
    – assets/angular-mocks

  2. Ben Thorner says:

    Thank you so much! I haven’t done much javascript testing, so got really confused by the variety of frameworks (rake, jasmine, karma, angular-mocks). You’re post is the first one I’ve seen to use the rake+jasmine+angular-mocks combination, which is exactly what I wanted.

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *