how to test controllers created with angular.module().controller() in Angular.js using Mocha

20,422

Solution 1

AngularJS provides mocks that make available some useful functions for dependency injection while testing.

Example:

(in jasmine)

Let's say we want to perform the first test from the official tutorial and we have defined a controllers module. (you could namespace the module name, but I want to keep it simple)

var Controllers = angular.module('controllers', []);

Controllers.controller('PhoneListCtrl', ['$scope', function($scope){
    $scope.phones = [{name: "Nexus S", snippet: "Fast..."},
                     {name: "Motorola XOOM...", snippet: "The Next...."},
                     {name: "MOTOROLA XOOM...", snippet: "The Next, Next..."}];
}]);

Then we create a module for out app and inject it our controllers module

var PhonesApp = angular.module('phoneApp', ['controllers']);

Finally we can test it like this

describe('phonesApp', function() {
    describe('phoneApp controllers', function() {
        beforeEach(module('controllers'));
        describe('PhoneListCtrl', function() {
            it('should create "phones" model with 3 phones',
                inject(function($rootScope, $controller) {

                var scope = $rootScope.$new();
                var ctrl = $controller("PhoneListCtrl", {$scope: scope });
                expect(scope.phones.length).toBe(3);
            }));
        });
    });
});

I haven't done it in mocha, but I guess the process is similar.

Pd: I did the tutorial using CoffeeScript, here are the relevant bits https://gist.github.com/4163147

Solution 2

If you're using mocha, beware that there is no support for angular.mock.module or angular.mock.inject unless you've upgraded to angular-1.1.1. I'm in the same boat, but I can't upgrade because of another issue.

I want to use mocha, because my server side tests are in mocha, and I'd prefer to have the same test framework on both sides, so I'm in a bit of a pickle.

So, if you can't use inject/module, then you can try it this way:

var $injector = angular.injector(['your-app-name', 'ng']),
  $controller = $injector.get('$controller'),
  $scope = $injector.get('$rootScope');

describe('my app controllers', function () {
  describe('FooCtrl', function () {
     it('should do something', function () {
        // scope can be any object you want; could be $rootScope from above
        var params = { $scope: { } },
          ctrl = $controller('FooCtrl', params);
        // TODO: test ctrl
     });
  });
});
Share:
20,422
Liviu
Author by

Liviu

Experienced full-stack senior, with a demonstrated history of working in the computer software industry. Strong professional skills in web based technologies

Updated on February 04, 2020

Comments

  • Liviu
    Liviu about 4 years

    I have a controller created with angular.module().controller() like in this situation

    myModule = angular.module('myApp.controllers', [])
                       .controller('testCtrl', ['$scope', function($scope){
                               $scope.test = 'this is a test';
                        }]);
    

    now, I need to use mocha to test if my controller is working properly. In Angular there are some examples when controllers are declared as global functions ( ex. http://docs.angularjs.org/tutorial/step_04 ), so they use

    function PhoneListCtrl() {...}
    .....
    beforeEach(function() {
       scope = {},
       ctrl = new PhoneListCtrl(scope);
    });
    
    it('shod test whatever PhoneListCtrl does ', function() {
       expect(scope.someProp).toBe('whateverValue');
    });    
    

    so the questions are:

    1) how can I do a similar test for controllers that are declared using angular.module().controller()

    2) how to do it using Mocha

  • metamatt
    metamatt about 11 years
    I'm still having the same problem (angular.mock.inject doesn't work) in Angular 1.1.2; this workaround helped; thanks! (angular.mock.inject exists and is callable for mocha, but isSpecRunning trips over a missing queue property, so it doesn't actually work.)
  • Jimchao
    Jimchao about 11 years
    Nice workaround, tried this solution and works well. But 1.1.4 version angular.mock works with mocha.
  • zenocon
    zenocon almost 11 years
    @Jimchao - yep, if you go with angular-unstable branch, they do support mocha with angular.module.mock and angular.mock.inject
  • srrvnn
    srrvnn about 9 years
    thank you for the explanation. using inject after module throws a weird error. can you please check this question: stackoverflow.com/questions/28802837/…