angularjs - simulacro de servicio angular/promesa en una prueba de karma/jazmín
unit-testing karma-runner (1)
¿Así que quieres probar, si tu servicio responde como se esperaba? Entonces, esto es algo que preferirías probar en el servicio. Los métodos basados en la promesa de prueba de unidad podrían verse así:
var mapService, $httpBackend, $q, $rootScope;
beforeEach(inject(function (_mapService_, _$httpBackend_, _$q_, _$rootScope_) {
mapService = mapService;
$httpBackend = _$httpBackend_;
$q = _$q_;
$rootScope = _$rootScope_;
// expect the actual request
$httpBackend.expect(''GET'', ''/onmap/rest/map/uuid?editor=true'');
// react on that request
$httpBackend.whenGET(''/onmap/rest/map/uuid?editor=true'').respond({
success: {
elements: [1, 2, 3]
}
});
}));
Como puede ver, no necesita usar $injector
, ya que puede inyectar los servicios necesarios directamente. Si desea utilizar los nombres de servicio correctos a lo largo de sus pruebas, puede inyectarlos con el prefijo y el sufijo "_", inject()
es lo suficientemente inteligente como para reconocer a qué servicio se refiere. También configuramos la $httpBackend
para cada especificación it()
. Y configuramos $q
$rootScope
para su posterior procesamiento.
Aquí es cómo puede probar que su método de servicio devuelve una promesa:
it(''should return a promise'', function () {
expect(mapService.getMapUuid(''uuid'', true).then).toBeDefined();
});
Como una promesa siempre tiene un método .then()
, podemos verificar si esta propiedad es una promesa o no (por supuesto, otros objetos también podrían tener este método).
A continuación, puede probar la promesa que obtiene resuelve con el valor adecuado. Puede hacer eso configurando un deferred
que resuelva explícitamente.
it(''should resolve with [something]'', function () {
var data;
// set up a deferred
var deferred = $q.defer();
// get promise reference
var promise = deferred.promise;
// set up promise resolve callback
promise.then(function (response) {
data = response.success;
});
mapService.getMapUuid(''uuid'', true).then(function(response) {
// resolve our deferred with the response when it returns
deferred.resolve(response);
});
// force `$digest` to resolve/reject deferreds
$rootScope.$digest();
// make your actual test
expect(data).toEqual([something]);
});
¡Espero que esto ayude!
Estoy tratando de escribir una prueba de karma / jazmín y me gustaría recibir algunas explicaciones sobre el funcionamiento de los simulacros en un servicio que está devolviendo una promesa. Te explico mi situación:
Tengo un controlador en el que hago la siguiente llamada:
mapService.getMapByUuid(mapUUID, isEditor).then(function(datas){
fillMapDatas(datas);
});
function fillMapDatas(datas){
if($scope.elements === undefined){
$scope.elements = [];
}
//Here while debugging my unit test, ''datas'' contain the promise javascript object instead //of my real reponse.
debugger;
var allOfThem = _.union($scope.elements, datas.elements);
...
Así es como mi servicio es:
(function () {
''use strict'';
var serviceId = ''mapService'';
angular.module(''onmap.map-module.services'').factory(serviceId, [
''$resource'',
''appContext'',
''restHello'',
''restMap'',
serviceFunc]);
function serviceFunc($resource, appContext, restHello, restMap) {
var Maps = $resource(appContext+restMap, {uuid: ''@uuid'', editor: ''@editor''});
return{
getMapByUuid: function (uuid, modeEditor) {
var maps = Maps.get({''uuid'' : uuid, ''editor'': modeEditor});
return maps.$promise;
}
};
}
})();
Y finalmente, aquí está mi prueba de unidad:
describe(''Map controller'', function() {
var $scope, $rootScope, $httpBackend, $timeout, createController, MapService, $resource;
beforeEach(module(''onmapApp''));
beforeEach(inject(function($injector) {
$httpBackend = $injector.get(''$httpBackend'');
$rootScope = $injector.get(''$rootScope'');
$scope = $rootScope.$new();
var $controller = $injector.get(''$controller'');
createController = function() {
return $controller(''maps.ctrl'', {
''$scope'': $scope
});
};
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
var response = {"elements":[1,2,3]};
it(''should allow user to get a map'', function() {
var controller = createController();
$httpBackend.expect(''GET'', ''/onmap/rest/map/MY-UUID?editor=true'')
.respond({
"success": response
});
// hope to call /onmap/rest/map/MY-UUID?editor=true url and hope to have response as the fillMapDatas parameter
$scope.getMapByUUID(''MY-UUID'', true);
$httpBackend.flush();
});
});
Lo que realmente quiero hacer es tener mi objeto de respuesta ({"elementos: ...}) como el parámetro de datos de la función fillMapDatas. No entiendo cómo simular todas las cosas del servicio (servicio, promesa, entonces)