在Angular应用程序的Karma测试文件中包含依赖项?

Ric*_*ard 43 javascript angularjs karma-runner

我正在尝试开始使用Karma测试,将它们添加到现有的Angular应用程序中.

这是我的主要应用定义文件:

angular
  .module('myApp', [
    'ngRoute',
    'moduleAdherence'
  ]);
Run Code Online (Sandbox Code Playgroud)

这是我的控制器文件:

   angular
    .module('moduleAdherence', [])
    .controller('AdherenceCtrl', ['$scope', function ($scope) {
      $scope.awesomeThings = [1,2,3,4];
    }]);
Run Code Online (Sandbox Code Playgroud)

这是我对文件的第一次尝试:

describe('Controller: AdherenceCtrl', function () {
  beforeEach(module('myApp'));
  var MainCtrl,
    scope;
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    MainCtrl = $controller('AdherenceCtrl', {
      $scope: scope
    });
  }));
  it('should attach a list of awesomeThings to the scope', function () {
    expect(scope.awesomeThings.length).toBe(4);
  });
});
Run Code Online (Sandbox Code Playgroud)

当我尝试运行它时grunt test,它失败并出现以下错误:

Uncaught Error: [$injector:nomod] Module 'd3' 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.
http://errors.angularjs.org/1.2.0/$injector/nomod?p0=d3
at /Users/me/Dropbox/projects/myapp/app/bower_components/angular/angular.js:1498
Run Code Online (Sandbox Code Playgroud)

我不明白这一点,因为这个控制器不使用D3.我在应用程序的其他地方使用D3,在指令中,但我没有在模块中注册它(我使用外部D3文件).

为什么Karma会注意到D3?没有D3,它不应该能够测试这个控制器吗?

小智 51

在karma配置文件(karma.conf.js)中,您需要定义所有库.

等等

    // list of files / patterns to load in the browser
    files: [
        'app/lib/angular/angular.js',
        'app/lib/angular-route/angular-route.js',
        'test/lib/angular-mocks.js',
        'app/app.js',
        'app/controllers/*.js',
        'app/services/*.js',
        'app/*',
        'test/spec/**/*.js'
    ],
Run Code Online (Sandbox Code Playgroud)

  • 这里的关键是app/app.js - 定义了角度模块 - 发生在所有引用角度模块的js文件之前 (2认同)

Nob*_*ita 34

有一个类似的问题和我的解决方案(由@danba评论启发)是以与在index.html中加载files完全相同的顺序加载脚本 .在我的情况下,像流氓模式一样app/scripts/**/*.js给业力造成了麻烦,因为业力不断引发错误.

也许不是复制所有脚本定义但最终工作的最优雅的解决方案,所以我的测试最终可以恢复运行.希望能帮助到你.

编辑:编辑这个,因为今天我可能(并希望)得到了这里出错的问题.因此,当在一个文件中定义相同模块并在许多不同文件中使用时,Karma似乎不喜欢通配模式.假设你的文件夹结构是这样的:

风险文件夹结构

假设AuthService.js您拥有该文件夹中所有服务的模块定义,以便该文件以以下内容开头:

angular.module('myApp.services', [
  'myApp.urls',
  'ngCookies'
])
Run Code Online (Sandbox Code Playgroud)

然后在所有其他文件中,您只是将其他服务附加到同一模块.在图片tokenService.js中将开始:

angular.module('myApp.services');
Run Code Online (Sandbox Code Playgroud)

如果一切都保持这种状态,一切都可能奏效.但是,如果我有可能以相反的方式定义模块,那么模块定义不再是该文件夹的第一个文件,而是另一个Karma读取之后AuthService它会抛出错误并拒绝完成测试.

解决方案1

解决方案可能是将模块定义放在自己的文件中,从下划线开始.最后,让所有兄弟姐妹文件都依赖于那个.所以上面的文件夹结构应该是:

更安全的文件夹结构

解决方案2

另-可能会更好-的解决方案是,以纪念在模块与一个共同的后缀/扩展例如定义文件service.module.js,而依赖于它的文件可以被正常命名一样authService.js,tokenService.js.此时的Karma配置将变为类似于:

// list of files / patterns to load in the browser
files: [
    'app/lib/angular/angular.js',
    'test/lib/angular-mocks.js',
    'app/app.js',
    'app/**/*.module.js', // <-- first the module definitions...
    'app/**/*.js', // <-- ..then all the other files
    'test/spec/**/*.js'
],
Run Code Online (Sandbox Code Playgroud)

这样,业力将首先加载模块定义,然后加载依赖于它们的那些文件.