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

May 19, 2014 Grant Hutchins

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.

About the Author

Biography

Previous
Cloud Foundry at the OpenStack Summit Atlanta 2014
Cloud Foundry at the OpenStack Summit Atlanta 2014

Last week we attended the OpenStack Summit Atlanta 2014 and we were amazed not only to see the great moment...

Next
Accessibility Testing – Javascript Library Roundup
Accessibility Testing – Javascript Library Roundup

If you’re a developer looking to build accessibility assertions into your own testing tool, there are a few...