28

Basically, I'm quite experienced with Mocha (written thousands of unit tests), and I'm quite new to AngularJS (written just my first project).

Now I am wondering how I might unit test all the AngularJS stuff using Mocha.

I know that Mocha runs in the browser, and I have already done this. But how do I structure and setup things?

I guess I need to:

  • Load AngularJS
  • Load Mocha
  • Load my tests

Within each of the tests, I need to load a controller, a service, ... to test. How do I do that? I am not using require.js or something like that, the files are just script files with basically the following content:

angular.controller('fooController', [ '$scope', function ($scope) {
  // ...
}]);

How do I reference and instantiate that controller within a test? The same holds true for services, directives, ...

Do I need to create mocks for $scope, $http & co. for myself, or is there some help?

Please note that I am aware that there is the Karma test runner (formerly known as Testacular), but I do not want to switch my test runner completely.

3
  • 1
    Even though you're not using Karma/Testacular, take a look at some of the examples in angular-seed. They show how you use angular-mocks to set up your modules for testing. Commented Apr 30, 2013 at 6:49
  • 4
    This is quite a useful article for testing using mocha: yearofmoo.com/2013/01/… Commented Jun 5, 2013 at 11:28
  • 2
    the angular-seed project isnt very helpful as it is using jasmine. Why aren't there examples using mocha and its adapter? Commented Jul 31, 2013 at 0:53

2 Answers 2

14

One way of doing that is to use Angular $injector in your tests:

myModule_test.js

suite('myModule', function(){
  setup(function(){
    var app = angular.module('myModule', []);
    var injector = angular.injector(['myModule', 'ng']);
    var service = injector.get('myService');
  });

  suite('myService', function(){
    test('should return correct value', function(){
       // perform test with an instance of service here
    });
  });
});

your html should look similar to this:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>myModule tests</title>
  <link rel="stylesheet" media="all" href="vendor/mocha.css">
</head>
<body>
  <div id="mocha"><p><a href=".">Index</a></p></div>
  <div id="messages"></div>
  <div id="fixtures"></div>
  <script src="vendor/mocha.js"></script>
  <script src="vendor/chai.js"></script>
  <script src="angular.min.js"></script>
  <script src="myModule.js"></script>
  <script>mocha.setup('tdd')</script>
  <script src="myModule_test.js"></script>
  <script>mocha.run();</script>
</body>
</html>
Sign up to request clarification or add additional context in comments.

Comments

3

If you're creating an angular service that doesn't have any dependencies and isn't necessarily angular specific, you can write your module in an angular-agnostic way, then either write a separate small angular wrapper for it, or test for the presence of angular, and conditionally create a service for it.

Here's an example of an approach that I use to create modules that can be used both in angular, the browser, and node modules, including for mocha tests:

(function(global) {
    //define your reusable component
    var Cheeseburger = {};

    if (typeof angular != 'undefined') {
        angular.module('Cheeseburger', [])
            .value('Cheeseburger', Cheeseburger);
    }
    //node module
    else if (typeof module != 'undefined' && module.exports) {
        module.exports = Cheeseburger
    }
    //perhaps you'd like to use this with a namespace in the browser
    else if (global.YourAppNamespace) {
        global.YourAppNamespace.Cheeseburger = Cheeseburger
    }
    //or maybe you just want it to be global
    else {
        global.Cheeseburger = Cheeseburger
    }
})(this);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.