私はAngularにかなり慣れており、Stack Overflowで同様に関連する質問をすべて確認しましたが、何も助けてくれませんでした。ユニットテストにサービスを挿入しようとするとエラーが発生します。コードを下に示しました-誰かが明らかなエラーを見つけられることを願っています。
次のように、モジュールを個別の。jsファイルで定義します。
angular.module('dashboard.services', []);
angular.module('dashboard.controllers', []);
ここで、EventingServiceというサービスを定義します(簡潔にするためにロジックは削除されています)。
angular.module('dashboard.services').factory('EventingService', [function () {
//Service logic here
}]);
EventingServiceを使用するコントローラーを次に示します(これはすべて実行時に正常に機能します)。
angular.module('dashboard.controllers')
.controller('Browse', ['$scope', 'EventingService', function ($scope, eventing) {
//Controller logic here
}]);
これが私の単体テストです-単体テストの実行時にエラーを引き起こすEventingServiceを挿入しようとする行:
describe('Browse Controller Tests.', function () {
beforeEach(function () {
module('dashboard.services');
module('dashboard.controllers');
});
var controller, scope, eventingService;
beforeEach(inject(function ($controller, $rootScope, EventingService) {
scope = $rootScope.$new();
eventingService = EventingService
controller = $controller('Browse', {
$scope: scope,
eventing: eventingService
});
}));
it('Expect True to be True', function () {
expect(true).toBe(true);
});
});
テストを実行すると、次のエラーが表示されます。
エラー:不明なプロバイダー:EventingServiceProvider <-EventingService
Jasmine specrunner.htmlファイルに必要なすべてのソースファイルが含まれていることを確認しました(これはAsp.Net MVCプロジェクトです)。
<!-- Include source files here... -->
@Scripts.Render("~/bundles/jquery")
<script type="text/javascript" src="@Url.Content("~/Scripts/angular.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/angular-mocks.js")"></script>
<script type="text/javascript" src="@Url.Content("~/App/scripts/app.js")"></script> <!-- Angular modules defined in here -->
<script type="text/javascript" src="@Url.Content("~/App/scripts/services/eventing.js")"></script> <!-- My Eventing service defined here -->
<script type="text/javascript" src="@Url.Content("~/App/scripts/controllers/browse.js")"></script> <!-- My Browse controller defined here -->
<!-- Include spec files here... -->
<script type="text/javascript" src="@Url.Content("~/App/tests/browse.js")"></script> <!-- The actual unit test here -->
私はなぜAngularがEventingServiceについて不平を言っているこのエラーを投げています。私のコントローラーは実行時に正常に動作します-それをテストしようとするとエラーが発生するので、私がモック/注射で何かを台無しにしているかどうかについて。
Angularテストのヘルプはゴミですので、私は現在困惑しています-誰でもできるヘルプや提案は非常に感謝されます。ありがとう。
私はこれに遭遇し、$ injectorを明示的に使用してサービスを取得するように切り替えることで解決しました:
var EventingService, $rootScope;
beforeEach(inject(function($injector) {
EventingService = $injector.get('EventingService');
$rootScope = $injector.get('$rootScope');
}));
これがなぜ機能するのか、なぜシンプルなのか
beforeEach(inject(function(EventingService) { .... }));
ありませんが、内部を調査する時間はありません。常に1つのコーディングスタイルを使用し、それに従うことをお勧めします。
このスタイルは、テストで使用する変数の名前がサービスの正しい名前であるという点で優れています。しかし、それは少し冗長です。
別のangular $ rootScopeのような奇妙な変数名を使用するマジック機能がありますが、そのハックな外観は好きではありません。
ほとんどの場合、モジュールが含まれていないため、このエラーが発生します。
beforeEach(module('capsuling'));
beforeEach(module('capsuling.capsules.services'));
コントローラー(dashboard.controllers
モジュール)は、異なるモジュール(dashboard.services
)モジュール署名の依存関係モジュールを参照する必要がある場合:
angular.module('dashboard.services', []);
angular.module('dashboard.controllers', ['dashboard.services']);
この質問はかなり古いですが、私はこれに似た問題を解決するのにかなりの時間を失いました、すなわち:
Error: Unknown provider: SomeServiceProvider <- SomeService
したがって、私はこの問題の別の考えられる原因をここに残しています。うまくいけば、誰かに役立つでしょう。
私の場合、私のプロジェクトにはまったく同じ名前の2つのモジュールがありましたが、異なる依存関係が作成されています。つまり、次の2つの異なる.jsファイルがあります:
angular.module('moduleName', [dependencies]))
From angular documentation:
1つの引数を渡すと、既存のangle.Moduleが取得されますが、複数の引数を渡すと、新しいangle.Moduleが作成されます
結論:テストで注入されたのは、誤った依存関係を持つモジュールであったことが判明しました。誤って作成されていたモジュールから2番目の引数を削除すると、問題は解決しました。
他の集約モジュールに依存する追加モジュールを次のように定義しようとしましたか?
angular.module( 'dashboard', [ 'dashboard.services', 'dashboard.controllers' ] )
したがって、beforeEachで、次のように両方のサブモジュールが定義されている1つのモジュールを指定できます。
describe('Browse Controller Tests.', function () {
beforeEach(function () {
module('dashboard');
});
var controller, scope, eventingService;
beforeEach(inject(function ($controller, $rootScope, EventingService) {
scope = $rootScope.$new();
eventingService = EventingService
controller = $controller('Browse', {
$scope: scope,
eventing: eventingService
});
}));
it('Expect True to be True', function () {
expect(true).toBe(true);
});
});