2013-07-02 10 views
19

Używamy karmy do testowania naszych usług kątowych, usługi te zawierają połączenia HTTP http, więc mamy wyśmiewany $ HTTPbackend w miejscu, dzięki czemu możemy uruchomić aplikację bez serwera i db. działa to dobrze, usługa może zadzwonić do $ http ("someurl? Id = 1234") i otrzymujemy właściwe dane.Angular 1.1.5 testowa usługa oparta na obietnicy

Ale gdy staramy się zrobić to samo w testach jednostkowych, nie możemy zmusić go do pracy, obietnica nie rozwiązuje, gdy chodzi o $ http

usługę:

getAllowedTypes: function (contentId) { 
    var deferred = $q.defer(); 
    $http.get(getChildContentTypesUrl(contentId)) 
     .success(function (data, status, headers, config) { 
      deferred.resolve(data); 
     }). 
     error(function (data, status, headers, config) { 
      deferred.reject('Failed to retreive data for content id ' + contentId); 
     }); 
    return deferred.promise; 
} 

szydzili $ httpbackend

$httpBackend 
    .whenGET(mocksUtills.urlRegex('/someurl')) 
    .respond(returnAllowedChildren); //returns a json object and httpstatus:200 

Test

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 

    $rootScope.$digest(); 

    expect(collection.length).toBe(3); 
}); 

ale kolekcja jest niezdefiniowana, .then() nigdy nie jest wywoływana.

próbowałem prawie wszystko, aby uzyskać obietnicę rozwiązania, $ rootScope. $ Apply(), $ strawienia, $ httpBacke.flush(), ale nic nie działa

Tak szydzili $ httpBackend działa, gdy wywołana z kontrolerami w app, ale nie wtedy, gdy usługi są wywoływane bezpośrednio w testach jednostek karmy.

Odpowiedz

7

Nie powinieneś potrzebować trawienia dwa razy, ponieważ wywołania $ httpBackend.flush() trawią się same. Musisz wykonać połączenie, wywołać syntezę, aby rozwiązać problemy przechwytujące, wywołać kolor.

Oto Plnkr pracy: http://plnkr.co/edit/FiYY1jT6dYrDhroRpFG1?p=preview

+1

Kees de Kooter dodał komentarz w innej odpowiedzi poniżej, że $ rootScope nie jest wymagane. Rozwidłem plunkr i skomentowałem wszystkie zastosowania $ rootScope. Test nadal przebiega: http://plnkr.co/edit/4ladJi7TAQ4sFdzuGmDr?p=preview – chashi

4

W twoim przypadku musisz $ digest dwa razy, raz dla $ httpBackend, i znowu dla twojego własnego odroczonego.

Więc:

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 
    $httpBackend.flush(); 
    $rootScope.$digest(); 

    expect(collection.length).toBe(3); 
}); 
+0

Tried .flush() już, ale staje się: "Błąd: Nie oczekiwaniu prośba do spłukiwania!" to wydaje się być powszechnym błędem od 1.1.4: https://github.com/angular/angular.js/issues/2431 –

+0

Kolejność jest tutaj niepoprawna, musisz wypróbować $ $ zanim spłyniesz. – user553086

4

jesteś prawie tam. W twoim przypadku wystarczy wymusić cykl trawienia przed opróżnieniem backendu HTTP. Zobacz przykładowy kod poniżej.

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 

    $rootScope.$digest(); 
    $httpBackend.flush(); 
    expect(collection.length).toBe(3); 
}); 
+0

To jest .flush() nr. $ Flush() btw, i nie, nie działa, otrzymasz komunikat "Brak oczekującego żądania przepłukania", patrz: https://github.com/angular/angular.js/issues/2431 –

+2

$ rootScope. $ digest() to IMO nie jest konieczne, jeśli testujesz usługę w izolacji. –

Powiązane problemy