how to test controllers created with angular.module().controller() in Angular.js using Mocha
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
});
});
});
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, 2020Comments
-
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 about 11 yearsI'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 about 11 yearsNice workaround, tried this solution and works well. But 1.1.4 version angular.mock works with mocha.
-
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 about 9 yearsthank you for the explanation. using inject after module throws a weird error. can you please check this question: stackoverflow.com/questions/28802837/…