私のアプリケーションには$http
、特定の仕様に従ってリクエストをフォーマットする を利用するサービスがあります。$httpBackend
応答をモックアップするために使用して、サービスのメソッドで単体テストを実行しようとしています。を使用するコントローラーとディレクティブをテストするとき、これで問題はありませんでした$http
が、私のサービスでは問題がありました。
ここで最初の回答のパターンに従っています: AngularJS - $http サービスを使用するサービス メソッドのテスト
つまり、予想されるリクエストを に登録し、$httpBackend
それに対するレスポンスを定義し、対象のサービスのメソッドを呼び出してから、バックエンド モックをフラッシュします。
$rootScope
を注入し、新しいスコープを作成して、対象$digest()
のサービス メソッドを呼び出した後にその上でを実行しない限り、これを機能させることはできません。これは、テスト ランナーと を使用するディレクティブのテストで使用するパターンです$http
。テスト ランナーは、それ以外の場合はフラッシュする保留中の要求がないことを示すためです。ただし、サービスでこの要件が必要になるとは思ってscope
いませんでした。サービスではあまり意味がありません。さらに、上記の質問への回答は、これが明示的に必要であることを示していません。
今朝かなり長い間Angularソースを調べた後、サービスの$http
リクエストに対してプロミスオブジェクトが正常に作成されていることを確認しましたが、プロミス解決関数は$q.when
の呼び出しに登録されていて、nextTick()
決して起動しないことがわかりました。servicesSpec でスコープ オブジェクトをダイジェストする行を追加した場合にのみ、すべてが起動します....
これは既知の問題ですか? v1.2.0rc2 を使用しています。テスト サービスをスコープ オブジェクトから切り離すための回避策はありますか?
参考までに、機能する仕様コードを次に示します。
describe("widget services", function () {
beforeEach(module('widget.services'));
describe("WidgetDB", function () {
var service, $httpBackend, scope;
beforeEach(inject(function ($rootScope, WidgetDB, _$httpBackend_) {
scope = $rootScope.$new();
service = WidgetDB;
$httpBackend = _$httpBackend_;
}));
it("should do something", function () {
$httpBackend.expectPOST(myUrl).respond(myResponse);
service.getChartData(myArguments);
scope.$digest(); // why do I need this for testing services?
$httpBackend.flush();
/* test evaluations */
});
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
});
});