AngularJS + Jasmine单元测试错误:[$ injector:modulerr]

时间:2016-02-08 17:46:22

标签: angularjs unit-testing jasmine

我使用角度和茉莉花进行单元测试。运行测试时出现以下错误:

  

结果消息:错误:[$ injector:modulerr]   http://errors.angularjs.org/1.4.9/ $注射器/ modulerr ...

单元测试

/// <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();
    });
});

控制器

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) {
    return {

        // simple method to do something asynchronously.
        someAsyncCall: function (x) {
            var deferred = $q.defer();
            $timeout(function () {
                deferred.resolve(x + '_async');
            }, 100);
            return deferred.promise;
        }
    };
});

最后,我的参考文件:

/// <reference path="angular.min.js" />
/// <reference path="angular-mocks.js" />
/// <reference path="angular-animate.min.js" />
/// <reference path="angular-sanitize.min.js" />
/// <reference path="angular-route.min.js" />
/// <reference path="jquery-2.1.1.min.js" />
/// <reference path="jquery.unobtrusive-ajax.js" />
/// <reference path="jquery.unobtrusive-ajax.min.js" />
/// <reference path="jquery.validate.min.js" />
/// <reference path="ui-bootstrap-tpls-0.14.3.min.js" />
/// <reference path="modernizr-2.8.3.js" />

当我在测试中的注入函数中设置一个断点并运行调试模式时,它会进入它。

1 个答案:

答案 0 :(得分:0)

尝试修改你的测试代码,我也冒昧地修改你的结构,这样你的测试可能会更有效率。对于较小的控制器/测试,无关紧要,但对于更复杂的功能,重置测试装置的能力使这更容易。

第一个beforeEach会将$injector注入到您可以用来获取引用的函数中。这可以在主describe函数中完成,因为它们可能不会更改。

第二个beforeEach我已嵌套在新的describe函数中。然后,您可以创建一组批处理的测试,其中每个it都可以保证新的/新的控制器实例。

如果$injector为null或未定义,则表示脚本未加载或以错误的顺序加载。为了更好地解决这个问题,你需要看看什么是注入失败,因为Angular还没有意识到它,在这种情况下,请注释完整的消息/ url,就像你开始在帖子的顶部,然后我们可以放置引用按照正确的顺序。

控制器文件

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

单元测试文件

/// <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 () {
        angular.mock.module("app"); // mock your module
    });

    // setup
    beforeEach(inject(function ($injector) {
        someServiceMock = jasmine.createSpyObj('someService', ['someAsyncCall']);
        someServiceMock.someAsyncCall.andReturn($q.when('weee'));

        var $rootScope = $injector.get("$rootScope");
        // $timeout = $injector.get("$timeout"); // not used anywhere that I can see
    }));

    describe('this will executes initial some set of tests on your controller', () => {
        var scope;
        var ctrl;
        beforeEach(inject(function ($controller) {
            scope = $rootScope.$new();
            ctrl = $controller('SampleController', {
                $scope: scope,
                someService: someServiceMock});
        }));

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

修改1

更改了参考文献。添加了角度模拟调用。