How do I test AngularJS code using Mocha?

All we need is an easy explanation of the problem, so here it is.

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.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

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" rel="nofollow noreferrer noopener">
</head>
<body>
  <div id="mocha"><p><a href="." rel="nofollow noreferrer noopener">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>

Method 2

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);

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply