unit-testing - run - unit test angular 6
AngularJS-Método de prueba de servicio que usa el servicio $ http (2)
Tengo una función en mi servicio que se parece a algo como esto:
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);
});
}
Quiero escribir una prueba de unidad para este método, pero no estoy seguro de cómo hacer que funcione. Básicamente, quiero probar que los datos enviados se construyeron correctamente a partir de los parámetros de la función y que se envió el encabezado de Autorización correcto.
He estado leyendo sobre cómo usar $httpBackend , pero en el ejemplo está probando un controlador, y solo las cosas que cambian en $ scope cuando se realizan y devuelven las solicitudes. ¿Hay alguna manera de lograr las pruebas que quiero? ¿O voy por algo mal?
Escribí una publicación en el blog sobre ese tema que muestra un poco sobre el uso de las simulaciones incorporadas de angular y la escritura de tus propias simulaciones, tal vez te ayude a obtener una comprensión más profunda:
¿Cómo burlarse de los módulos de AngularJS e inyectarlos en tus pruebas?
En resumen, define un segundo módulo para pruebas que puede simular el comportamiento deseado:
var apptastic = angular.module(''apptastic'', []),
apptasticMock = angular.module(''apptasticMock'', []);
Y sobrescribe el comportamiento original, por ejemplo, así:
apptasticMock.service("socket", function($rootScope){
... // overwrite
});
Luego, debe cargarse en las pruebas; esto funciona porque los servicios ya definidos sobrescriben los servicios en el orden en que se cargan:
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 buena estructura de código, incluso la herencia no es realmente un problema a la vez que se puede tener un control preciso sobre lo que se debe burlar y lo que se debe usar del código original.
Los servicios de prueba no difieren mucho de los controladores de prueba, por lo que los principios son los mismos. Básicamente necesitas:
- Inyectar objetos bajo prueba.
- configuración de simulacros (si corresponde): aquí estaba en el camino correcto usando $ httpBackend mock
- ejecuta métodos en tu objeto bajo prueba y verifica los resultados
Si después de probar que los métodos de un servicio dan como resultado una llamada de $ http POST, puede escribir su prueba de esta manera (se omiten las partes no esenciales):
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();
});
Aquí está el jsFiddle de trabajo que ilustra esta prueba en acción: http://jsfiddle.net/pkozlowski_opensource/MkrjZ/2/
Una última observación: es mejor no usar .alert () en las pruebas unitarias ya que esas alertas pausarán la ejecución de las pruebas.