1

ネストされた promise を使用する関数をテストしようとしています (この関数は変更できないと仮定しましょう)。これらの約束を処理するには$rootScope.$digest()、少なくとも 2 回呼び出す必要があります。$digest()10msごとに呼び出すこの実用的なソリューションを思いつきました。

// Set some async data to scope.key
// Note: This function is just for demonstration purposes.
//       The real code makes async calls to localForage.
function serviceCall(scope, key) {
  var d1 = $q.defer(), d2 = $q.defer();

  setTimeout(function () {
    d1.resolve('d1');
  });

  d1.promise.then(function (data) {
    setTimeout(function () {
      d2.resolve(data + ' - d2');
    }, 100); // simulate longer async call
  });

  d2.promise.then(function (data) {
    scope[key] = data;
  });
}

it('nested promises service', function (done) {
  var interval = setInterval(function () {
      $rootScope.$digest();
    }, 10),
    myKey = 'myKey',
    scope = {};

  serviceCall(scope, myKey);

  setTimeout(function () {
    expect(scope[myKey]).toEqual('d1 - d2');
    window.clearInterval(interval);
    done();
  }, 120); // What is the right timeout?
});

問題は、すべての promise を解決するのに十分な時間を消化するために必要なタイムアウト時間を見積もることです。サービスがローカルストレージなどに対して実際の非同期呼び出しを行うと、さらに複雑になります。

これを解決する別の方法はありますか?残りのすべての約束を取得する方法はありますか?

4

1 に答える 1

2

ジャスミンスパイを使用して外部サービス呼び出しをモック/スタブアウトする必要があるため、サービスがいつ解決/拒否されるかを制御できます。サービスには、その内部機能をバックアップするテストが必要です。

この例は完全ではありませんが、わかりやすくするために省略されていることに注意してください。

var service = jasmine.createSpyObj('service', ['call']);
var defServiceCall;
var $scope;

beforeEach(function () {
  module('myModule', function ($provide) {
    // NOTE: Replaces the service definition with mock.
    $provide.value('service', service);
  });
  inject(function($q, $rootScope) {
    $scope = $rootScope.$new();
    defServiceCall = $q.defer();
    service.call.and.returnValue(defServiceCall.promise);
  });
});
describe('When resolved', function () {
  beforeEach(function () {
    myFunctionCall(); // Sets myVar on the scope
    defServiceCall.resolve('data');
    $scope.$digest(); // NOTE: Must digest for promise to update
  });
  it('should do something awesome when resolved', function () {
    expect($scope.myVar).toEqual('data');
  });
});
于 2015-05-27T18:36:43.663 に答える