2015-05-18 6 views
6

mi sto cercando di fare una prova di unità di un servizio nel mio casoCome scrivere un test unitario per la richiesta http?

Nel mio test controller

myService.getItem('/api/toy/' + scope.id).success(
    function(toy) { 
     $scope.toy = toys.details; 
    } 
); 

MyService

angular.module('toyApp').service('myService', ['$http', 
    function($http) { 
     var service = {}; 
     return { 
      getItem: function(url) { 
       return $http.get(url); 
      }, 
     }; 
    } 
]); 

file di prova.

describe('toy ctrl', function() { 
    var $httpBackend, ctrl, myService; 

    beforeEach(module('toyApp')); 

    beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_, __myService_) { 
     scope = _$rootScope_.$new(); 
     $httpBackend = _$httpBackend_; 
     myService = _myService_; 

     ctrl = _$controller_('toyCtrl', { 
      $scope: scope 
     });  

    })); 

    describe('call my service', function() { 
     it('should make request when app loads', function() { 
      $httpBackend.expectGET('/api/toy/123').respond({id:123, detail:456 }); 
      myService.getItem('/api/toy/123').then(function(toy){ 
       expect(scope.toy.detail).toBe(456); 
      }) 
      $httpBackend.flush(); 
    }) 
}) 

sto ottenendo

Error: Unexpected request: GET /api/toy/123 
No more request expected 

Se prendo $httpBackend.flush(), l'errore è andato ma non coprirà la parte

function(toy) { 
     $scope.toy = toys.details; 
    } 

. Voglio coprire la chiamata di funzione e non sono sicuro di come farlo. Qualcuno può aiutarmi? Grazie mille

+0

Sei unità di test del controller o servizio (dovrebbe fare richiesta quando i carichi dell'app sembra li controller ke)? – PSL

+0

Sto testando il servizio all'interno del mio controller – FlyingCat

+1

Ok. in quel caso potresti semplicemente prendere in giro il tuo servizio e iniettarlo sul controller. E il valore del test rispetto all'ambito. Fondamentalmente quello che sto cercando di dire è che quando si controlla l'unità di test del controller è sufficiente testare la logica del controller 'myService.getItem ('/ api/toy/123')' è irrilevante in realtà. – PSL

risposta

3

Sembra che tu stia "unitamente" testando il controller, in modo da non dover portare il servizio in figura poiché è sufficiente testare la logica del controller. È possibile creare un servizio di simulazione e iniettarlo durante la creazione del controller nel test.

Esempio:

var mockItem = {details:{//somestuff}, id:'1'};// set up a mock object to test against later 
//.... 
beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_, _$q_) { 
    scope = _$rootScope_.$new(); 
    $httpBackend = _$httpBackend_; 

    //Set up mock 
    myService = jasmine.CreateSpyObj('myService', ['getItem']); 
    myService.getItem.and.returnValue($q.when(mockItem)); 

    ctrl = _$controller_('toyCtrl', { 
     $scope: scope, 
     myService: myService //<-- Pass it here 
    });  

})); 


    //.....Assuming you are making the call when controller is instantiated 
    it('should make request when app loads', function() { 
    expect(myService.getItem).toHaveBeenCalled(); 
    //You could also check as below 
    //expect(myService.getItem).toHaveBeenCalledWith(expectedidpassedin); 
    scope.$digest(); //Resolve $q promise callback 
    expect($scope.toy).toEqual(mockItem .details); 
    }); 

se si è specificamente unità di testare il servizio da soli si potrebbe fare:

it('should make request when app loads', function() { 
     var resp; 
     $httpBackend.expectGET('/api/toy/123').respond({id:123, detail:456}); 
     myService.getItem('/api/toy/123').then(function(response){ 
      resp = response.data; 
     }); 
     $httpBackend.flush(); 
     expect(resp.detail).toEqual(456); 
}); 

Nel vostro controller, invece di concatenamento success uso then

myService.getItem('/api/toy/' + scope.id).then(
    function(response) { 
     $scope.toy = response.toys.details; 
    }); 
+0

Grazie. Sto ricevendo un errore quando uso. Quindi, sembra che non riesca a trovare la risposta se lo uso. +1 – FlyingCat

+0

@FlyingCat Questo non dovrebbe essere un problema. allora è una parte di q promessa. il successo fa parte della promessa http che è solo un involucro di q promessa. Quindi dovrebbe essere disponibile ovunque. Assicurati anche di fare '$ q.quando (dati)' nel tuo test. Si noti inoltre che quando si utilizza 'then'' response.data' è la risposta che si ottiene un primo argomento nella callback 'successe ' – PSL