在Angular中,有没有理由不用模块声明列出模块依赖性?

时间:2014-05-24 19:27:55

标签: angularjs unit-testing

在我阅读有关Angularjs的所有教程和示例中,他们都定义了带有空列表的模块作为第二个参数:

angular.module('myModule', []);

我知道创建新模块需要存在第二个参数,但我不明白为什么列表中没有任何元素。 angular.module的文档没有说明列表内容的含义。

但是,从定义我的app模块我理解列表代表新模块所依赖的模块 - 那么为什么app子模块总是空的?例如,在我自己的项目中,我有一个用户模块,我的应用程序依赖于该模块:

/* app.js */
angular.module('myApp', [
    'ngCookies',
    'ngResource',
    'ui.bootstrap',
    'ui.router',
    'myApp.system',
    'myApp.users'
]);

angular.module('myApp.system', []);
angular.module('myApp.users', []);

当我终于开始学习如何使用业力和茉莉花进行单元测试时,我花了好几个小时试图弄清楚这个错误信息:

Error: [$injector:modulerr] Failed to instantiate module myApp.users due to:
Error: [$injector:unpr] Unknown provider: $stateProvider
http://errors.angularjs.org/1.2.13/$injector/unpr?p0=%24stateProvider
        at /Users/matt/Development/myApp/public/lib/angular/angular.js:3556
        at getService (/Users/matt/Development/myApp/public/lib/angular/angular.js:3683)
        at invoke (/Users/matt/Development/myApp/public/lib/angular/angular.js:3710)
        at /Users/matt/myApp/public/lib/angular/angular.js:3639

最终我找到了两个可以解决这个问题的方法 - 要么我可以在测试代码中加载模块依赖项,要么我可以将依赖项添加到users模块声明中的空列表中:

/* UserControllerTest.js */
describe('UserCtrl', function () {

    var $rootScope,
        $scope,
        controller;

    beforeEach(function () {
        module('ui.router');
        module('myApp.system');
        module('ngResource');
        module('myApp.users');

        inject(function ($injector) {
            $rootScope = $injector.get('$rootScope');
            $scope = $rootScope.$new();
            controller = $injector.get('$controller')('UserCtrl', {$scope: $scope});
        });
    });

    it('should work', function () {
        expect(true).toBe(true);
    });

});

或者:

/* app.js */
...
angular.module('myApp.users', [
    'ngResource',
    'ui.router',
    'mean.system'
]);

我有什么理由不想做后者吗?为什么我从未在文档和教程中看到它 - 它会阻止我在测试中模拟这些依赖项吗?

为什么我不需要后一个子模块定义来定期运行我的应用程序?我确实有一系列注射当地人'为UserCtrl指定 - 为什么不足以进行单元测试?

1 个答案:

答案 0 :(得分:3)

模块的目的是封装代码的自包含部分(例如,可重用的小部件,代码tgst实现特定的功能等)。通常,让每个模块声明它依赖的依赖项是一个好习惯。

如果没有,那么模块依赖于模块,它要求它声明那些依赖性,这会混淆“自我遏制”,损害可测试性和可重用性,并引入一堆如果潜在的未来错误。

也就是说,似乎没有理由不向每个模块声明依赖关系。 (不,它不会阻止你在单元测试中模拟依赖项。)正如人们所预料的那样,即使多个模块需要,每个模块也会加载一次。

API参考确实不是非常详细的angular.module,但 Developer Guide 有更广泛的描述。

例如,引用“依赖关系”部分:

  

模块可以将其他模块列为其依赖项。根据模块的不同,需要在加载需求模块之前加载所需的模块。换句话说,所需模块的配置块在需求模块的配置块之前执行。运行块也是如此。 每个模块只能加载一次,即使有多个其他模块需要它