web-dev-qa-db-ja.com

Angular app?のKarmaテストファイルに依存関係を含めますか?

既存の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なしでこのコントローラーをテストすることはできませんか?

43
Richard

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

同様の問題があり、私の解決策(@danbaコメントに触発された)は、index.htmlでロードされたのと同じ順序でexactfilesにスクリプトをロードすることでした私の場合、app/scripts/**/*.jsはカルマにトラブルを引き起こし、常にエラーを投げていました。

すべてのスクリプト定義をコピーするための最もエレガントなソリューションではないかもしれませんが、最終的には機能したので、テストは最終的に実行できるようになりました。それが役に立てば幸い。

編集:これを編集するのは、おそらく今日(そして)うまくいけば)したがって、同じモジュールが1つのファイルで定義され、多くの異なるファイルで使用される場合、Karmaはグロビングパターンを好まないようです。あなたのフォルダ構造が次のようなものだとしましょう:

risky folder structure

AuthService.jsそのフォルダ内のすべてのサービスのモジュール定義があるため、そのファイルは次のように始まります。

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

次に、他のすべてのファイルで、同じモジュールに他のサービスをアタッチしています。写真の中の tokenService.jsは次で始まる:

angular.module('myApp.services');

すべてがこのようにとどまる場合、すべてがおそらく動作します。しかし、万が一モジュールを逆方向​​に定義した場合、モジュール定義はそのフォルダーの最初のファイルではなく、カルマがAuthServiceの後に読み込む別のフォルダーにありますエラーをスローし、テストの完了を拒否します。

解決策1

解決策は、アンダースコアで始まる独自のファイルにモジュール定義を配置することです。最後に、すべての兄弟ファイルがそのファイルに依存するようにします。したがって、上記のフォルダー構造は次のようになります。

safer folder structure

解決策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は最初にモジュール定義をロードし、次にそれらに依存するファイルをロードします。

34
Nobita

上記の@Nobitaによるソリューション#1と、@ danbaのコメントに基づいて、私のために働いた簡単なソリューションがあります。

Karma.conf.jsで、残りを取り込むパターンの上に前提条件ファイルを明示的にロードします。

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

Karmaは、このパターンが「module.js」にも一致することを気にしていないようです。

1
sb333

常に縮小されていないバージョンのangular=をカルマにロードします。エラーが表示され、何を変更すべきかを見つけるのに役立ちます。あなたの場合、カルマによってロードされるファイルの順序です。

1

スクリプトタグなどで何かを含めていないことをindex.htmlで確認します。

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

すべてのJavascriptファイルがkarma.config.jsに含まれている必要があります

1
lars1595

私も同じ問題を抱えていました。私の場合、モジュールごとにいくつかのファイルがあったために問題が発生しました。モジュールごとに1つのファイルのみを含めることでこれを解決しました。