【问题标题】:Include dependencies in Karma test file for Angular app?在 Angular 应用程序的 Karma 测试文件中包含依赖项?
【发布时间】:2013-11-21 21:58:13
【问题描述】:

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

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

angular
  .module('myApp', [
    'ngRoute',
    'moduleAdherence'
  ]);

这是我的控制器文件:

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

这是我第一次尝试文件:

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

当我尝试使用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

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

为什么 Karma 会注意到 D3?是不是应该不用D3也能测试这个控制器?

【问题讨论】:

  • 模块myApp在哪里定义?还有MainCtrl?
  • 抱歉 - 重命名以供公众使用时的拼写错误,现已修复。问题还是一样。
  • 想通了 - 我必须在 karma.config.jsfiles 部分中显式加载依赖项。
  • @Richard 很好,请添加它作为解决方案!
  • 使用karma-angular-filesort

标签: javascript angularjs karma-runner


【解决方案1】:

在 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'
    ],

【讨论】:

  • 这里的关键是app/app.js——定义了角度模块的地方——出现在所有引用角度模块的js文件之前
【解决方案2】:

有一个类似的问题,我的解决方案(受到@danba 评论的启发)是按照 exact 与 index.html 中加载的顺序相同的顺序加载 files 中的脚本。 在我的例子中,像app/scripts/**/*.js 这样的通配模式给业力带来了麻烦,不断地抛出错误。

也许不是复制所有脚本定义的最优雅的解决方案,但最终可以正常工作,因此我的测试最终可以重新运行。希望对您有所帮助。

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

假设在AuthService.js 中,您在该文件夹中有所有服务的模块定义,因此该文件以:

angular.module('myApp.services', [
  'myApp.urls',
  'ngCookies'
])

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

angular.module('myApp.services');

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

解决方案 1

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

解决方案 2

另一个 - 可能更好 - 解决方案是使用通用后缀/扩展名标记定义模块的文件,例如 service.module.js,而依赖它的文件通常可以命名为 authService.jstokenService.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'
],

这样 karma 将首先加载模块定义,然后加载依赖它们的文件。

【讨论】:

  • 我也有同样的问题。我正在寻找更好的解决方案。
  • @GordonSun 检查我的更新,希望它适用于您的用例,看看这是否真的解决了其他人的问题可能会很有趣。
  • 我也有同样的问题。我喜欢#2...似乎是一个很好的妥协
  • 谢谢。你让我今天一整天都感觉很好。实验性地得出解决方案#2,但没有“首先是模块定义......”。
  • 第二种解决方案对我有用,谢谢!在这里待了一个多星期!
【解决方案3】:

我也遇到了同样的问题,在我的情况下,出现问题是因为每个模块有多个文件,这是一种不好的做法,因为我们可以指向未初始化的模块。通过每个模块只包含一个文件解决了这个问题。

【讨论】:

  • 遇到了同样的问题,通过按顺序添加脚本'app/scripts/app.js', 'app/scripts/**/*Module.js', 'app/scripts/*.js', 'app/scripts/**/*.js' 解决了这个问题,这样所有包含模块声明的文件都包含在所有可能需要模块的文件之前。
  • “我们每个模块有多个文件”到底是什么意思?
【解决方案4】:

始终将非缩小版本的 angular 加载到 karma 中。 它将显示错误并帮助您更好地找出要更改的内容。 在您的情况下,这是 karma 加载文件的顺序。

【讨论】:

    【解决方案5】:

    检查您的 index.html 是否包含脚本标记之类的内容。

     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5angular-resource.js"
    

    你所有的 Javascript 文件都需要在你的 karma.config.js 中

    【讨论】:

      【解决方案6】:

      这是一个对我有用的简单解决方案,基于@Nobita 的上述解决方案#1,以及@danba 的评论。

      在 karma.conf.js 中,将先决条件文件显式加载到引入其余部分的模式之上:

      files: [
          ...
          'app/module.js',
          'app/*.js'
      ]
      

      Karma 似乎并不介意该模式也匹配“module.js”。

      【讨论】:

      • 谢谢,这让我更进一步!
      猜你喜欢
      • 1970-01-01
      • 2015-03-05
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 2011-08-04
      相关资源
      最近更新 更多