既存のAngular=アプリにKarmaテストを追加して、Karmaテストを開始しようとしています。
これが私のメインアプリ定義ファイルです。
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ファイルを使用しています)。
なぜカルマはD3に気付いているのですか? D3なしでこのコントローラーをテストすることはできませんか?
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'
],
同様の問題があり、私の解決策(@danbaコメントに触発された)は、index.htmlでロードされたのと同じ順序でexactでfiles
にスクリプトをロードすることでした私の場合、app/scripts/**/*.js
はカルマにトラブルを引き起こし、常にエラーを投げていました。
すべてのスクリプト定義をコピーするための最もエレガントなソリューションではないかもしれませんが、最終的には機能したので、テストは最終的に実行できるようになりました。それが役に立てば幸い。
編集:これを編集するのは、おそらく今日(そして)うまくいけば)したがって、同じモジュールが1つのファイルで定義され、多くの異なるファイルで使用される場合、Karmaはグロビングパターンを好まないようです。あなたのフォルダ構造が次のようなものだとしましょう:
AuthService.js
そのフォルダ内のすべてのサービスのモジュール定義があるため、そのファイルは次のように始まります。
angular.module('myApp.services', [
'myApp.urls',
'ngCookies'
])
次に、他のすべてのファイルで、同じモジュールに他のサービスをアタッチしています。写真の中の tokenService.js
は次で始まる:
angular.module('myApp.services');
すべてがこのようにとどまる場合、すべてがおそらく動作します。しかし、万が一モジュールを逆方向に定義した場合、モジュール定義はそのフォルダーの最初のファイルではなく、カルマがAuthService
の後に読み込む別のフォルダーにありますエラーをスローし、テストの完了を拒否します。
解決策は、アンダースコアで始まる独自のファイルにモジュール定義を配置することです。最後に、すべての兄弟ファイルがそのファイルに依存するようにします。したがって、上記のフォルダー構造は次のようになります。
別の-おそらくより良い-解決策は、モジュールが共通の接尾辞/拡張子で定義されているファイルをマークすることです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'
],
この方法で、karmaは最初にモジュール定義をロードし、次にそれらに依存するファイルをロードします。
上記の@Nobitaによるソリューション#1と、@ danbaのコメントに基づいて、私のために働いた簡単なソリューションがあります。
Karma.conf.jsで、残りを取り込むパターンの上に前提条件ファイルを明示的にロードします。
files: [
...
'app/module.js',
'app/*.js'
]
Karmaは、このパターンが「module.js」にも一致することを気にしていないようです。
常に縮小されていないバージョンのangular=をカルマにロードします。エラーが表示され、何を変更すべきかを見つけるのに役立ちます。あなたの場合、カルマによってロードされるファイルの順序です。
スクリプトタグなどで何かを含めていないことをindex.htmlで確認します。
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5angular-resource.js"
すべてのJavascriptファイルがkarma.config.jsに含まれている必要があります
私も同じ問題を抱えていました。私の場合、モジュールごとにいくつかのファイルがあったために問題が発生しました。モジュールごとに1つのファイルのみを含めることでこれを解決しました。