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

我正在尝试开始使用Karmatesting,将它们添加到现有的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的情况下testing这个控制器吗?

在karmaconfiguration文件(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' ], 

有一个类似的问题,我的解决scheme(从@danba评论中得到的启发)是按照它们在index.html中加载的顺序加载files中的脚本。 在我这种情况下,像app/scripts/**/*.js .js这样的通配模式正在给业务不断带来错误的业务造成麻烦。

也许不是最好的解决scheme来复制所有的脚本定义,但最终工作,所以我的testing终于可以恢复运行。 希望能帮助到你。

编辑:编辑这个,因为今天我可能(并希望 )得到了这里出了问题的hang </s>。 所以,当同一个模块被定义在一个文件中并被用在许多不同的文件中时,Karma似乎不喜欢匹配模式。 假设您的文件夹结构如下所示:

高风险的文件夹结构

假设在AuthService.js你有你的模块定义为该文件夹中的所有服务,以便该文件开始:

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

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

 angular.module('myApp.services'); 

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

解决scheme1

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

更安全的文件夹结构

解决scheme2

另一个可能更好的解决scheme是使用通用后缀/扩展名(例如service.module.js )来标记定义模块的文件,而依赖于它的文件可以像authService.jstokenService.js一样正常命名。 那个时候的噶玛configuration会变成这样:

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

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

我也有同样的问题,在我的情况下发生问题,因为每个模块有几个文件,这是一个不好的做法,因为我们可以指向没有初始化模块。 通过每个模块只包含一个文件来解决这个问题。

始终将angular度的非缩小版本加载到业力中。 它会显示错误,并帮助您更好地了解要更改的内容。 在你的情况下,这是由业力加载的文件的顺序。

检查你的index.html,你不包括像脚本标签的东西。

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

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

这是一个简单的解决scheme,对我来说,基于@Nobita的解决scheme#1,以及@ danba的评论。

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

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

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