web-dev-qa-db-ja.com

ジャスミン単体テストで$ q.allの約束を解決する方法は?

私のコントローラーには次のようなコードがあります:

$q.all([qService.getData($scope.id), dService.getData(), qTService.get()])
.then(function (allData) {
  $scope.data1 = allData[0];
  $scope.data2 = allData[1];
  $scope.data3 = allData[2];
});

そして私のユニットテストでは、私はこのようなことをしています:

beforeEach(inject(function($rootScope, $q, $location){// and other dependencies... 
  qServiceSpy = spyOn(_qService, 'getData').andCallFake(function () {
    var data1 = {
      id: 1,
      sellingProperty: 1,
    };
    var d = $q.defer();
    d.resolve(data1);
    return d.promise;
  });

  dServiceSpy = spyOn(_dService, 'getData').andCallFake(function () {
    var data2 = [{ "id": "1", "anotherProp": 123 }];
    var d = $q.defer();
    d.resolve(data2);
    return d.promise;
  });
  qTServiceSpy = spyOn(_qTService, 'get').andCallFake(function () {
    var data3 = [{ id: 0, name: 'Rahul' }];
    var d = $q.defer();
    d.resolve(data3);
    return d.promise;
  });
  rootScope = $rootScope;
});

今、私のテストでは、サービスが呼び出され、data1、data2が未定義ではないかどうかを確認しています。

it('check if qService' got called, function() {
  expect(scope.data1).toBeUndefined();
  rootScope.$digest();
  expect(_quoteService.getQuote).toHaveBeenCalled();
});
it('check if "data1" is defined', function () {
  expect(scope.data1).toBeUndefined();
  rootScope.$digest();
  expect(scope.data1).toBeDefined();
});

私の問題は、コントローラーの個々のサービス呼び出しをq.allに置き換え、テストでscope.$applyrootScope.$digestに置き換えるまで、これはうまく機能していたことです。 q.allおよびrootScope.$digestscope.$applyを使用して試行)を使用すると、両方のテストがエラーで失敗します。

10個の$ digest()反復に到達しました。中止!

rootScope.$digestを削除すると、promiseは解決されず、テストは失敗します

未定義が定義されると予想されます。

q.allを使用してコードを単体テストする方法はありますか?

出会った この投稿

しかし、$digestを既に使用しようとしているので、これも役に立ちません。

31
Rahul R.

$rootScope.$apply()コールバック関数にafterEach()を入れてみてください。約束はAngularの$apply()で解決します。

afterEach(function(){
    rootScope.$apply();
});
62
Thomas Schultz