How do I inject dependencies into AngularJS controller tests without using Jasmine-specific injection ()

I am trying to wrap my brain around dependency injection in AngularJS. Let's say this is my very interesting application code:

function PrideRockCtrl($scope, King) { $scope.king = King; } angular.module('Characters', ['ngResource']) .factory('King', function() { return "Mufasa"; }); 

I want to test PrideRockCtrl . If I follow the examples in the documentation and in the tutorial, I could use module('Characters') to configure the injector and use inject() to get some dependencies. i.e:.

 describe('Pride Rock', function() { beforeEach(module('Characters')); it('should be ruled by Simba', inject(function($rootScope, $controller) { var scope = $rootScope.$new(); var ctrl = $controller(PrideRockCtrl, {$scope: scope}); expect(scope.king).toEqual("Mufasa"); })); }); 

This works great, but it is not a cross-testing solution. The test assistants module() and inject() are only compatible with Jasmine.

What is the best way to manually perform the same dependency injection without using module() or inject() ?

I came up with this:

 describe('Pride Rock', function() { it('should be ruled by Mufasa', function() { var $injector = angular.injector(['Characters']); var $controller = $injector.get('$controller'); var scope = $injector.get('$rootScope').$new(); var king = $injector.get('King'); var ctrl = $controller(PrideRockCtrl, {$scope: scope, King: king}); expect(scope.king).toEqual("Mufasa"); }); }); 

It seems very verbose. Is there a better way?

jsFiddle: http://jsfiddle.net/johnlindquist/d63Y3/

+8
angularjs
source share
2 answers

The simplest version without using modules will look like this:

 describe('Pride Rock', function() { it('should be ruled by Simba', inject(function($rootScope, $controller) { var scope = $rootScope.$new(); var ctrl = $controller(PrideRockCtrl, { $scope: scope, King:"Mufasa" }); expect(scope.king).toEqual("Mufasa"); })); }); 

In fact, you were pretty close to your attempts, the only thing missing was the local dependency in the controller ( King:"Mufasa" ).

In tests like those where we focus on only one selected class, there is no need to use the $ injector, since we can manually fool / drown our dependencies. At the end of the day, the $ injector simply gives instances of objects, so we can create those that belong to us.

+5
source share
Controllers

Angular are just JS functions. If you do not want to enter anything, just call them.

 describe('king should be set', function() { var scope = {}; var lion = "Simba"; PrideController(scope, lion); expect(scope.king).toEqual(lion) }); 
+4
source share

All Articles