2013-05-01 8 views
30

Moje kontroler ma kod jak poniżej:

$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]; 
}); 

I w moich testów jednostkowych robię coś takiego:

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; 
}); 

Teraz w moim teście jestem sprawdzenie, czy usługi są nazywane i dane1, dane2 nie są niezdefiniowane ..

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(); 
}); 

mój problem jest, to działa dobrze, dopóki nie zastępuje moje indywidualnych zgłoszeń serwisowych w sterowniku z q.all i w testach scope.$apply z rootScope.$digest. Z q.all i rootScope.$digest (wypróbowany przy scope.$apply również) oba testy nie powiedzie się z powodu błędu:

10 $digest() iterations reached. Aborting!

Jeśli usunąć rootScope.$digest następnie obietnice nigdy się nie rozwiązuje i testów zawiedzie mówiąc

expected undefined to be defined.

jakiejkolwiek pomocy, jak czy powinienem testować kody jednostkowe z q.all?

natknąłem this post

Ale to również nie pomaga, jak ja już próbuje użyć $digest.

Odpowiedz

61

Możesz spróbować umieścić $rootScope.$apply() w funkcji oddzwaniania afterEach(). Obietnice zostaną rozstrzygnięte na $apply() w Angular.

afterEach(function(){ 
    rootScope.$apply(); 
}); 
+3

W przypadku, gdy zastanawiam się, gdzie to jest udokumentowane: [Różnice między Kris Kowal Q i $ q] (http://docs.angularjs.org/api/ng/service/$q#differences-between-kris- kowal-sq-and-q) & [testowanie] (http://docs.angularjs.org/api/ng/service/$q#testing) –

+1

$ scope.apply() zrobił mi sztuczkę – Mikey

+14

'$ apply 'zwykle otrzymuje wywołanie zwrotne. Wolę 'scope. $ Digest()', który tylko trawi bieżący zakres, więc ma lepszą wydajność. –

Powiązane problemy