Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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

share|improve this question

2 Answers

up vote 10 down vote accepted

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(),
                  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

share|improve this answer

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 b/c of another issue.

I want to use mocha, b/c 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|improve this answer
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.) – metamatt Feb 14 at 1:43
Nice workaround, tried this solution and works well. But 1.1.4 version angular.mock works with mocha. – Jimchao Apr 20 at 2:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.