2013-07-02 15 views
19

Usiamo il karma per testare i nostri servizi angolari, questi servizi contengono chiamate $ http, quindi abbiamo un $ httpbackend deriso sul posto in modo che possiamo eseguire l'app senza server e db. funziona bene, un servizio può chiamare $ http ("someurl? Id = 1234") e otteniamo i dati corretti.Servizio basato su promessa di prova angolare 1.1.5

Ma quando cerchiamo di fare la stessa cosa in unit test, non possiamo farlo funzionare, la promessa non si risolve, quando si tratta di $ http

Il servizio:

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

Il $ schernito httpbackend

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

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

ma la raccolta non è definito, .then() non viene mai chiamato.

provato praticamente di tutto per ottenere la promessa di risolvere, $ rootScope. $ Applicare(), $ digerire, $ httpBacke.flush(), ma nulla funziona

Così deriso $ httpBackend funziona quando viene chiamato dai controller in app, ma non quando i servizi vengono chiamati direttamente nei test dell'unità karma

risposta

7

Non è necessario digerire due volte, poiché $ httpBackend.flush() chiama digest stesso. È necessario effettuare la chiamata, chiamare digest per risolvere gli interceptor della richiesta, il call flush.

Ecco un Plnkr di lavoro: http://plnkr.co/edit/FiYY1jT6dYrDhroRpFG1?p=preview

+1

Kees de Kooter ha fatto un commento in un'altra risposta di seguito che $ rootScope non è richiesto. Ho biforcato il plunkr e ho commentato tutti gli usi $ rootScope. Il test continua ancora: http://plnkr.co/edit/4ladJi7TAQ4sFdzuGmDr?p=preview – chashi

4

Nel tuo caso, devi digerire $ due volte, una volta per $ httpBackend, e ancora per il tuo differito.

Quindi:

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

.flush provato() già, ma ottiene: "Errore: Non richiesta in sospeso per irrigare!" questo sembra essere un errore comune dal 1.1.4: https://github.com/angular/angular.js/issues/2431 –

+0

L'ordine non è corretto qui, è necessario digerire $ prima di svuotare. – user553086

4

ci sei quasi. Nel tuo caso, devi solo forzare un ciclo di digest prima di svuotare il back-end HTTP. Vedi il codice di esempio qui sotto.

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

è .flush() no. $ Flush() btw, e nope, non funziona, visualizza "Nessun errore di richiesta di scarico", vedi: https://github.com/angular/angular.js/issues/2431 –

+2

$ rootScope. $ digest() è IMO non necessario se si sta testando un servizio in isolamento. –

Problemi correlati