2016-05-02 15 views
5

Ho appena iniziato a scrivere i miei primi test di unità in AngularJS tramite Jasmine.

In qualche modo ancora non capisco perché dovrei prendere in giro $ httpBackend. Per rendere chiaro ciò che è ancora chiaro per me Annoterò un piccolo esempio:

Immaginate Ho un servizio(myService) che sta ricevendo i dati da un URL:

function getData() { 
    return $http.get("http://example.com/data") 
     .then(function (response) { 
      return response.data; 
     }); 
} 

Supponiamo che un GET chiamare all'URL "http://example.com/data" restituisce i seguenti dati:

{ 
    firstname: "John", 
    lastname: "Doe" 
} 

la corrispondente prova sarebbe simile a questa:

describe("Service: myService", function() { 

    beforeEach(module("myApp")); 

    var myService, $httpBackend; 

    beforeEach(inject(function (_myService_, _$httpBackend_) { 
     myService = _myService_; 
     $httpBackend = _$httpBackend_; 
    })); 

    afterEach(function() { 
     $httpBackend.verifyNoOutstandingExpectation(); 
     $httpBackend.verifyNoOutstandingRequest(); 
    }); 

    it("should get data", function() { 
     var mockData = {datakey: "datavalue"}; 
     $httpBackend.whenGET("http://example.com/data").respond(mockData); 

     var promise = myService.getData(); 
     $httpBackend.flush(); 

     promise.then(function(response){ 
      expect(response).toEqual(mockData) 
     }); 
    }) 
}); 

Se non erro, il test deve passare, anche se i dati deriso non è uguale ai dati reali. Il test passerebbe sempre, indipendentemente dal modo in cui ho impostato i Dati derisi, poiché la funzione di servizio verrebbe sempre reindirizzata a quanto impostato in $ httpBackend.whenGET ("http://example.com/data") .respond (mockData);.

ho pensato lo scopo di una tale prova è quello di verificare se i dati restituiti da una chiamata GET [in questo caso myService.getData()] è davvero i dati previsti e non alcuni dati deriso casuali. Quindi, qual è il vero punto di derisione dei dati invece di controllare se myService.getData restituisce i dati reali {firstname: "John", lastname: "Doe"}?

Sono ben consapevole che potrei anche impostare i dati deriso per {cognome: "John", cognome: "Doe"}, ma quando i dati reali del URL sarebbe dinamica, il beffe dei dati e i dati reali non sarebbero uguali di nuovo.

Grazie in anticipo!

+1

Si sta accertando di chiamare l'URL corretto. –

risposta

3

Bisogna fare in qualche modo tra:

  • Unità alla prova
  • Integrazione test
  • end-to-end test

Quello che vuoi è quello di unit test del getData() funzione. Presumo che non ti interessi se i dati sono corretti in questo caso o meno. Quello che vuoi fare è se l'URL giusto viene chiamato.

Pertanto, si sta verificando che questa unità del codice funzioni come previsto.

Prendete questo esempio:

var add = function(endpoint) { 
    var sum = 0; 
    endpoint().then(function(numberArray) { 
    numberArray.forEach(number) { 
     sum = sum + number; 
    } 
    }); 

    return sum; 
}; 

Quando si deridere il httpBackend qui, in realtà non si cura se si ottiene un 1,2,3 o 5,6,7 indietro.Vuoi assicurarti di aggiungere qualsiasi numero, aggiungerli e restituirli.

Il tuo caso è molto più semplice, quindi è possibile verificare se l'URL è giusto, e il gioco è fatto.

Un test end-to-end dovrebbe anche includere un backend corretta e controlla se il dato è ok.

Il AngularJS documentation rende chiaro:

it('should fetch authentication token', function() { 
    $httpBackend.expectGET('/auth.py'); 
    var controller = createController(); 
    $httpBackend.flush(); 
}); 

In questo esempio, si vuole fare in modo che si sta chiamando il diritto URL/endpoint. Se si ottiene realmente il token corretto, è più appropriato un test di integrazione o un test end-to-end che richiama quindi il vero backend.

+0

Quindi ogni volta che sto testando le richieste HTTP GET in un test unitario, l'obiettivo è controllare se viene chiamato l'URL giusto e non se è stato impostato il dato corretto? –

+0

Dalla mia esperienza e dalle mie letture, sì! Un test unitario significa che stai testando la funzionalità di una funzione, un'unità della tua applicazione. L'aspetto dei dati non è in gran parte parte di esso, dal momento che la funzione dovrebbe reagire di conseguenza (lancia errori, ecc.) –

+0

Grazie per il vostro tempo. Ma poi mi sto ancora chiedendo perché qualcuno dovrebbe usare (come in molti tutorial su $ httpBackend) dati simulati e confrontarlo con i dati della funzione corrispondente che sta facendo la richiesta http invece di controllare solo se l'URL viene chiamato o meno (come nel tuo esempio sopra). Ecco un Plunker per dimostrare cosa intendo: http://plnkr.co/edit/XcWySIWtIJ3QCIOB0iJB?p=info –