2013-05-15 18 views
9

Sto lavorando con AngularJS + Karma. configService gestisce le impostazioni della mia app (ad esempio il colore di sfondo, se è in modalità di debug, autorizzazioni generali ...). Carica i dati iniziali con $ http. Ho scritto il test con successo per il servizio ma le mie direttive e controller lo usano.AngularJS + Karma: riutilizzare un servizio simulato quando si controllano le unità o le unità di controllo

Quando scrivo i test di unità per le direttive, devo prendere in giro il servizio.

So che posso fare:

spyOn(configService, 'getBackgroundColor').andCallFake(function (params) { 
    return "red"; 
}); 

ma il servizio ha 25+ metodi e caricamento dei dati iniziali. Non ho voglia di scrivere (e mantenere) questa cosa di spionaggio in ogni suite di test. Inoltre, carico i dati in fabbrica con $ http e anche questo dovrebbe essere preso in giro. se faccio l'iniezione del servizio e sto prendendo in giro le chiamate, eseguirò comunque la richiesta get http.

Quale pensi che sarebbe il modo migliore per riutilizzare un finto?

+0

Vuoi solo condividere una simulazione del servizio tra molti test? O stai cercando un modo per deridere la chiamata $ http e utilizzare il servizio nei test di direttiva e controller? –

+0

condividi la simulazione del servizio tra molte suite di test. più specificamente, evitare di incollare una copia prima di Each(). Ieri ho creato un servizio in un modulo 'myapp.mocks' e l'ho incluso in testacular.conf.js, e poi lo carico con' module (myapp.mocks) '. Ho estratto anche la risposta del mio server in un altro file e ho creato un 'var RESPONSE_SERVER = {json here}'. se questa sembra una buona soluzione, elaborerò di più e risponderò al di sotto di –

+1

Questo è praticamente ciò che stavo per raccomandare. Ho creato un file .js che conteneva solo una semplice vecchia funzione javascript che ho chiamato per creare il mock. Un'altra semplice funzione javascript per configurare le risposte del server per i test.E come dici tu, se definisci una variabile globale con le risposte JSON, puoi utilizzarla nei tuoi confronti per confrontarla. –

risposta

0

Ho creato un file .js che conteneva solo una semplice vecchia funzione javascript che ho chiamato per creare il mock. Un'altra semplice funzione javascript per configurare le risposte del server per i test. E come dici tu, se si definisce una variabile globale con le risposte JSON quindi è possibile utilizzare che i test per confrontare contro

8

invece di spruzzare il codice di prova di spie è possibile creare una vera e propria simulazione del servizio in il proprio modulo e aggiungerlo in qualsiasi test che ne abbia bisogno.

Il test dell'unità di controllo si trova in un file test/spec/modules/user/controller.js.

Il servizio deriso si trova in un file test/mock/modules/user/service.js.

Per un metodo di controllo:

$scope.refreshList = function() { 
    UserService.all(pageNumber, size, sort, function(data) { 
    $scope.users = data.content; 
    $scope.page = data.page; 
    }); 
}; 

il servizio deriso:

(function() { 

'use strict'; 

angular.module('app.user.mock', ['app.user']); 

angular.module('app.user.mock').factory('UserServiceMock', 
    ['$q', 
    function($q) { 
    var factory = {}; 

    factory.mockedUsers = { 
     content: [ { firstname: 'Spirou', lastname: 'Fantasio', email: '[email protected]', workPhone: '983743464365' } ], 
     page: '1' 
    }; 

    factory.search = function(searchTerm, page, size, sort, callback) { 
     var defer = $q.defer(); 
     defer.resolve(this.mockedUsers); 
     defer.promise.then(callback); 
     return defer.promise; 
    }; 

    factory.all = function(page, size, sort, callback) { 
     var defer = $q.defer(); 
     defer.resolve(this.mockedUsers); 
     defer.promise.then(callback); 
     return defer.promise; 
    }; 

    return factory; 
    } 
]); 

})(); 

e il test di unità di controllo:

(function() { 

'use strict'; 

var $scope; 
var listController; 
var UserServiceMock; 

beforeEach(function() { 
    module('app.project'); 
    module('app.user.mock'); // (1) 
}); 

beforeEach(inject(function($rootScope, _UserServiceMock_) { 
    $scope = $rootScope.$new(); 
    UserServiceMock = _UserServiceMock_; // (2) 
})); 

describe('user.listCtrl', function() { 

    beforeEach(inject(function($controller) { 
    listController = $controller('user.listCtrl', { 
     $scope: $scope, 
     UserService: UserServiceMock 
    }); 
    })); 

    it('should have a search function', function() { // (3) 
    expect(angular.isFunction(UserServiceMock.search)).toBe(true); 
    }); 

    it('should have an all function', function() { 
    expect(angular.isFunction(UserServiceMock.all)).toBe(true); 
    }); 

    it('should have mocked users in the service', function() { 
    expect(UserServiceMock.mockedUsers).toBeDefined(); 
    }); 

    it('should set the list of users in the scope', function(){ 
    expect($scope.users).not.toEqual(UserServiceMock.mockedUsers); 
    $scope.refreshList(); 
    $scope.$digest(); 
    expect($scope.users).toEqual(UserServiceMock.mockedUsers.content); 
    }); 

}); 

})(); 

si aggiunge il modulo contenente app.user.mock il servizio mocked (1) e iniettare il servizio beffardo nel controller (2).

È quindi possibile eseguire il test del servizio di simulazione che è stato iniettato (3).

+0

Conoscete un modo per ottenere il gelsomino in una finta come questa? In modo che io possa usare 'jasmine.spyOn' invece di tracciare le chiamate a mano. – dshepherd