Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

code A guest post by Christopher Hiller, the author of Developing an AngularJS Edge and a Software Architect for Decipher, Inc. He enjoys gaming, coding, and gleaming the cube. He can be reached on GitHub or as @misterhiller on Twitter.

If you haven’t read my previous post on modularization, you might want to take a look, since I cover how to get your AngularJS app organization in top shape. In this post we will look at writing tests and stomping bugs in AngularJS.

Perhaps you have thousands of lines of AngularJS JavaScript, and yet only a few unit tests? Even in The Age of the Unit Test, it happens. If you have bugs piling up, you may want to consider writing some tests.

Writing Tests

It’s tedious to spend large chunks of time writing tests against old code. You aren’t developing anything new, nor are you fixing problems. You’re instead asserting that your code does what it does. I don’t recommend this approach. Even if you love writing unit tests, this sort of monotony will eventually spoil it for you.

The natural starting point is bug fixes. Squash a bug, write a test, run your tests and the bug stays squashed. New bugs are bad enough, but undead bugs are especially frustrating.

Writing tests is easy when you have examples to cut and paste, but when you’re starting from scratch, figuring out fixtures can be daunting. Don’t fear the fixtures! AngularJS makes it easy.

Look at the following silly, troublesome (perhaps not silly enough) directive:

You could take several approaches to testing this directive, including spying on the getRandomTemplate() and getRandomColor() functions (a la Sinon.JS), but for the sake of brevity, we’ll just stub. Enter the $provide service.

Enter Fixtures

Try this fixture (in Mocha or Jasmine syntax; you will also want the optional, but recommended, ngMock module):

Above, you are “decorating” a service–effectively modifying it on-the-fly. For the purposes of your test, any component that injects RandomService will receive your new functions in place of the originals. $provide.decorator() can fully overwrite any injectable if you wish–just return something other than $delegate.

Do you need only some of the tests to use a decorator? describe() calls are nestable; just put your decorations in the appropriate function scope.

If you don’t really need your dependency at all, or a module’s config() or run() block does something you’d rather avoid, you can fully define a module within your test suite. In most cases, though, it’s easier to just decorate.

This technique can be used for the majority of your dependencies, thanks to AngularJS’ highly testable architecture. Dependencies also come into play via Scope hierarchies. For instance, you may have a controller that relies upon a parent Scope’s members. Splendidly, the $controller service lets you override the injector at the point of instantiation:

Note that if controller Baz injects factory MyFactory and service MyService in addition to $scope, you can use $controller to pass it anything you like instead:


Generally speaking, fixtures in AngularJS tests are no more complicated than what I’ve shown above. You don’t have to mock out globals or create complex object hierarchies, and you don’t have to include forty source files. Writing tests while stomping bugs is an effective and simple way to improve code coverage on large AngularJS apps.

For more details about AngularJS, see the resources below from Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Developing an AngularJS Edge is intended for intermediate JavaScript programmers. No attempt has been made to explain the JavaScript syntax used (except in the cases where AngularJS may introduce a peculiarity), nor do we explain concepts such as closures, function chaining, callbacks, or other common patterns. What we do explain are basic AngularJS concepts, components, and their applications. We provide examples along the way, answer questions, and correct common misconceptions. Together, we’ll build a working single-page weblog application using AngularJS, which will help you become proficient with using AngularJS to go out and create your own applications.
Develop smaller, lighter web apps that are simple to create and easy to test, extend, and maintain as they grow. AngularJS is a hands-on guide that introduces you to AngularJS, the open source JavaScript framework that uses Model–view–controller (MVC) architecture, data binding, client-side templates, and dependency injection to create a much-needed structure for building web applications.
Instant AngularJS Starter is designed to get you ramped up on AngularJS as quickly and efficiently as possible. By the end of this book, you’ll possess all of the knowledge you need to make full-featured, real-life applications with AngularJS. The code samples are reusable, and specifically intended to give you a head start on your next project. This book will transform your curiosity about AngularJS into a set of production-ready AngularJS skills, through a broad overview of the framework and deep dives into its key features.

Tags: AngularJS, Bugs, fixtures, Jasmine, Javascript, Mocha, ngMock, Stomp, tests,

One Response to “Writing Tests and Stomping Bugs in AngularJS”

  1. Ben

    Nice – I like this decorator approach. Supposing, though, that you wanted to re-use your ‘RandomService’ decorator elsewhere in your test suite, what approach would you prefer for doing so?