steveareeno February 2016

AngularJS + Jasmine unit test Error: [$injector:modulerr]

I am leanring unit testing with angular and jasmine. I am getting the following error when running the tests:

Result Message: Error: [$injector:modulerr] http://errors.angularjs.org/1.4.9/$injector/modulerr...

Unit Test

/// <reference path="../Scripts/_references.js" />
/// <reference path="jasmine.js" />
/// <reference path="SampleController.js" />

describe('Controller Unit Test: ', function () {
    var scope, ctrl, $timeout;
    var someServiceMock;

    beforeEach(function () {
        module('app');
    });

    beforeEach(function () {
        someServiceMock = jasmine.createSpyObj('someService', ['someAsyncCall']);
        inject(function ($rootScope, $controller, $q, _$timeout_) {
            scope = $rootScope.$new();
            someServiceMock.someAsyncCall.andReturn($q.when('weee'));
            $timeout = _$timeout_;
            ctrl = $controller('SampleController', {
                $scope: scope,
                someService: someServiceMock
            });
        });
    });

    it('Controller exists', function () {
        expect(ctrl).toBeDefined();
    });
});

Controller

var app = angular.module('myApp', []);
app.controller('SampleController', function ($scope, someService) {

    //set some properties
    $scope.foo = 'foo';
    $scope.bar = 'bar';

    //add a simple function.
    $scope.test1 = function () {
        $scope.foo = $scope.foo + '!!!';
    };

    //set up a $watch.
    $scope.$watch('bar', function (v) {
        $scope.baz = v + 'baz';
    });

    //make a call to an injected service.
    $scope.test2 = function () {
        someService.someAsyncCall($scope.foo)
          .then(function (data) {
              $scope.fizz = data;
          });
    };
});

app.factory('someService', function ($timeout, $q) {
    re        

Answers


Igor February 2016

Try modifying your test code like so, I also took the liberty of modying your structure so that way your tests might be a bit more efficient. For smaller controllers / tests it does not matter but for more complex functionality the ability to reset for a test set makes this easier.

The 1st beforeEach will inject $injector into the function which you can use to get your references. This can be done in the main describe function as they will likely not change.

The 2nd beforeEach I have nested in a new describe function. You can then create a batched set of tests where each it is guaranteed a fresh/new controller instance.

If $injector is null or undefined it means that the scripts are not being loaded or being loaded in the wrong order. To better troubleshoot this you need to see what is failing the injection because Angular is not yet aware of it, in that case please comment with the full message/url like you started to at the top of your post and we can then put the references in the correct order.

Controller file

/// <reference path="jquery-2.1.1.min.js" />
/// <reference path="angular.min.js" />
... rest of your code

Unit test file

/// <chutzpah_reference path="angular.min.js"/>
/// <chutzpah_reference path="angular-mocks.js"/>
// you might need additional chutzpah_reference but it really depends on your chutzpah configuration found in chutzpah.json
/// <reference path="jquery-2.1.1.min.js" />
/// <reference path="angular.min.js" />
/// <reference path="angular-mocks.js" />
/// <reference path="jasmine.js" />
/// <reference path="SampleController.js" />

describe('Controller Unit Test: ', function () {
    var $rootScope;  //, $timeout;
    var someServiceMock;

    beforeEach(function () {
        angu 

Post Status

Asked in February 2016
Viewed 2,821 times
Voted 14
Answered 1 times

Search




Leave an answer