Question

I am testing some Angular.js code with Jasmine. To do this I need an Angular injector:

var injector = angular.injector(['ng', 'ngRoute', 'mainModule']);

This works fine, but when I get to testing a controller that uses $location, I have to add that to the injector:

var injector = angular.injector(['ng', 'ngRoute', 'location', 'mainModule']);

Now this throws an error:

Error: Error: [$injector:modulerr] Failed to instantiate module location due to:
Error: [$injector:nomod] Module 'location' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

How can I include $location service there? Thanks.

-------------- EDIT -----------------

due to not many answers I thought I will add some details.

Here is a controller I am trying to test (or the definition of it, I won't be pasting all code):

var app = angular.module('mainModule');

app.controller('appController', ['$window', '$scope', '$location', '$wsService', '$userService', '$labelService', function ($window, $scope, $location, $wsService, $userService, $labelService) {
    //body of the controller
}]);

You have already seen how I create the injector in my unit test in the original post, here is how I use the injector to create the controller:

var scope;
var controller;
var getController = function() {
    injector.invoke( ['$rootScope', '$controller', function ($rootScope, $controller) {
        scope      = $rootScope.$new();
        controller = $controller('appController', {$scope: scope});
    }]);
};

Hope this will help with producing some potential answers. Thanks

Was it helpful?

Solution

To answer my own question. Here is how to test the following controller:

var app = angular.module('mainModule');

app.controller('appController', ['$window', '$scope', '$location', '$userService', function ($window, $scope, $location, $userService) {
    //body of the controller
}]);

1 In unit test create injector:

var injector = angular.injector(['ng', 'ngRoute', 'mainModule']);

2 Invoke services required:

injector.invoke( ['$userService',  function ($userService) {
    service     = $userService;
}]);

3 Mock location service:

var mockLocation = {
    path : ""
};

I just needed path for the controller I am testing, thus I did not mock anything else, but mock whatever else you need.

4 Invoke the controller:

var scope;
var controller;
var getController = function() {
    injector.invoke( ['$rootScope', '$controller', function ($rootScope, $controller) {
        scope      = $rootScope.$new();
        controller = $controller('appController', {$scope: scope, $location: mockLocation});
    }]);
};

Now the controller can be used in unit tests.
This did get rid of 'unknown provider' and other errors related to location service.
This blog post helped me with an answer, thanks to the author.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top