2015-01-15 15 views
9

Sto avendo un'unità problema testare il seguente metodo:Come unità di prova di un metodo incatenato utilizzando Jasmine

$scope.changeLocation = function (url) { 
     $location.path(url).search({ ref: "outline" }); 
    }; 

ho scritto il seguente test di unità che attualmente non riesce con questo errore (TypeError: Impossibile leggere proprieta 'di ricerca' di non definito):

var $locationMock = { path: function() { }, search: function() { } }; 

it('changeLocation should update location correctly', function() { 
     $controllerConstructor('CourseOutlineCtrl', { $scope: $scope, $location: $locationMock }); 

     var url = "/url/"; 
     spyOn($locationMock, "path"); 
     spyOn($locationMock, "search"); 

     $scope.changeLocation(url); 

     expect($locationMock.search).toHaveBeenCalledWith({ ref: "outline" }); 
     expect($locationMock.path).toHaveBeenCalledWith(url); 
    }); 

Se cambio la mia funzione al seguente, il test viene superato:

$scope.changeLocation = function (url) { 
     $location.path(url); 
     $location.search({ ref: "outline" }); 
    }; 

Come posso testare questo metodo quando utilizzo il metodo di concatenazione? Devo configurare il mio $ locationMock in modo diverso? Per la vita di me non riesco a capirlo.

risposta

18

Questo è perché il vostro finto non restituisce posizione oggetto da essere in grado di catena attraverso. Utilizzando Jasmine 2.0 è possibile cambiare il vostro finto a:

var $locationMock = { path: function() { return $locationMock; }, 
         search: function() { return $locationMock; } }; 

e

spyOn($locationMock, "path").and.callThrough(); 
spyOn($locationMock, "search").and.callThrough(); //if you are chaining from search 

o aggiungere:

spyOn($locationMock, "path").and.returnValue($locationMock); 
spyOn($locationMock, "search").and.returnValue($locationMock); //if you are chaining from search 

O semplicemente creare un oggetto di spionaggio (meno codice):

var $locationMock = jasmine.createSpyObj('locationMock', ['path', 'search']); 

e

$locationMock.path.and.returnValue($locationMock); 
$locationMock.search.and.returnValue($locationMock); //if you are chaining from search 
+1

Stavo usando Jasmine 1.x quindi il .and.returnValue() non funzionava. Questo funziona benissimo per Jasmine 2.0. Ho modificato il .and.returnValue() con .andReturns() per farlo funzionare con 1.x. Aggiornerò presto Jasmine. Grazie per l'aiuto! – nweg

+0

@nweg Siete i benvenuti. Grazie per la modifica. :) – PSL

+0

Grazie a @PSL per il puntatore. Restituire lo stesso oggetto nei metodi da incatenare (modello builder) è la chiave qui. Ben illustrato. – Rajaraman

0

prova:

spyOn($locationMock, "path").and.callThrough(); 

Else you'r chiamando ricerca su un non finto $ location

Problemi correlati