2012-08-23 15 views
19

Ho una funzione sul mio servizio che assomiglia a qualcosa questo:

addStatement: function(user, action, object) { 
      var statement = { 
        user: user, 
        action: action, 
        object: object 
      }; 
      $http({ 
       method: 'POST', 
       url: '/foo/bar', 
       data: statement, 
       headers: {Authorization: 'Basic YWxhZGRpbjpvcGVuIHNlc2FtZQ=='} 
      }).success(function(data) { 
       alert("success: " + data); 
      }); 
     } 

Voglio scrivere uno unit test per questo metodo, ma non sono sicuro Come farlo funzionare. Fondamentalmente, voglio verificare che i dati inviati siano stati costruiti correttamente dai parametri di funzione e che sia stata inviata l'intestazione di autorizzazione corretta.

Ho letto su come usare $httpBackend, ma nell'esempio si sta verificando un controller, e basta inserire le modifiche su $ scope quando le richieste vengono fatte e restituite. C'è un modo per raggiungere i test che voglio? O sto andando su qualcosa di sbagliato?

risposta

37

I servizi di verifica non differiscono molto dai controllori di test, quindi i principi sono gli stessi. Fondamentalmente è necessario:

  • Iniettare oggetti in prova
  • schernisce impostazione (se presente) - qui eravate sulla strada giusta usando $ httpBackend finte
  • Metodi di girare sul vostro oggetto in prova e verificare i risultati

Se sei dopo la prova che un metodi del servizio si traduce in $ http POST chiamano si potrebbe scrivere il test come questo (parti non essenziali omessi):

beforeEach(module('MyApp')); 
beforeEach(inject(function(MyService, _$httpBackend_) { 
    service = MyService; 
    $httpBackend = _$httpBackend_; // angular strips the underscores so 
            // we don't need to use unique names 
    // https://docs.angularjs.org/api/ngMock/function/angular.mock.inject 
})); 

it('should invoke service with right paramaeters', function() { 
    $httpBackend.expectPOST('/foo/bar', { 
     "user": "testUser", 
     "action": "testAction", 
     "object": {} 
    }, function(headers){ 
     return headers.Authorization === 'Basic YWxhZGRpbjpvcGVuIHNlc2FtZQ=='; 
    }).respond({}); 
    service.addStatement('testUser', 'testAction', {}); 
    $httpBackend.flush(); 
}); 

Ecco la jsFiddle lavoro illustra questo test in azione: http://jsfiddle.net/pkozlowski_opensource/MkrjZ/2/

Un'ultima osservazione: è meglio non usare .alert() in unit test poiché tali avvisi saranno sospendere l'esecuzione del test.

+0

+1 per evitare 'alert's. Un'altra possibilità è che potresti voler inserire '$ window' e usare' $ window.alert' in modo da poterlo prendere in giro per i tuoi test. – btford

+0

Momento di apprendimento: se si elimina '$ httpBackend.flush();' il test non sarà come previsto. –

2

ho scritto un post su questo argomento molto mostrando un po 'sull'utilizzo di angolari prende in giro da incasso e scrivere i propri prende in giro, forse aiuta a ottenere una comprensione più profonda:

How to mock AngularJS modules and inject them in your testacular tests?

In breve definisce un secondo modulo per il test che può prendere in giro il comportamento desiderato:

var apptastic  = angular.module('apptastic', []), 
    apptasticMock = angular.module('apptasticMock', []); 

E sovrascrive il comportamento originale, ad es. in questo modo:

apptasticMock.service("socket", function($rootScope){ 
... // overwrite 
}); 

Allora deve essere caricato nelle prove - Questo funziona perché sovrascrive angolari servizi già definiti nell'ordine in cui sono stati caricati:

describe("Socket Service", function(){ 
    var socket; 

    beforeEach(function(){ 
    module('apptastic'); 
    module('apptasticMock'); 

    inject(function($injector) { 
     socket = $injector.get('socket'); 
    }); 
    }); 

    it("tests something", function(){ 
    ... // test 
    }); 

}); 

Con una bella struttura del codice, anche l'eredità non è davvero un problema pur essendo in grado di avere un controllo a grana fine su ciò che dovrebbe essere deriso, e cosa dovrebbe essere usato dal codice originale.

Problemi correlati