angular - ¿Cómo puedo probar la respuesta JSON de map() en jasmine?
Cuál es la mejor manera de probar la respuesta JSON de map() en un servicio de Jasmine.
En este código, puedo obtener todas mis alarmas de tipo desde ws. Ahora quiero probar este servicio. Para esto intenté algo de código como el siguiente.
public typegetall(): Observable<Alarm[]> {
...
return this.http.get(Api.getUrl(Api.URLS.typegetall), {
headers: headers
})
.map((response: Response) => {
let res = response.json();
if (res.StatusCode === 1) {
this.auth.logout();
} else {
return res.StatusDescription.map(alarm => {
return new Alarm(alarm);
});
}
});
}
Intenté esta prueba unitaria:
describe(`Service`, () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AlarmsTableComponent],
imports: [],
providers: [
{ provide: AlarmsService]
}).compileComponents()
.then(() => {
myComponent = TestBed.createComponent(AlarmsTableComponent).componentInstance;
myService = TestBed.get(AlarmsService);
});
});
afterEach(inject([HttpTestingController], (backend: HttpTestingController) => {
backend.verify();
}));
it('alarms get all', inject([AlarmsService], (alarmeservice: AlarmsService) => {
expect(alarmeservice.typegetall());
}));
});
¿Puedes darme alguna idea para probar esto?
Editar :
it('should return reasonable json ssss', inject([AlarmsService, MockBackend], fakeAsync((service: AlarmsService, mockBackend) => {
const mockResponse = {
data: [
{ alarmnumber: 0, alarmdesc: 'All cats are lions' },
{ alarmnumber: 1, alarmdesc: 'Video 1' },
{ alarmnumber: 2, alarmdesc: 'Video 2' },
{ alarmnumber: 3, alarmdesc: 'Video 3' },
]
};
mockBackend.connections.subscribe(connection => {
connection.mockRespond(new Response(
new ResponseOptions({
body: [
{ alarmnumber: 0, alarmdesc: 'All cats are lions' },
{ alarmnumber: 1, alarmdesc: 'Video 1' },
{ alarmnumber: 2, alarmdesc: 'Video 2' },
{ alarmnumber: 3, alarmdesc: 'Video 3' },
]
})));
});
service.typegetall().subscribe(alarmstype => {
console.log(alarmstype)
expect(alarmstype.length).toBe(3);
expect(alarmstype[0].alarmdesc).toEqual("All cats are lions");
});
tick();
})));
el resultado: Error: No se pueden hacer XHRs dentro de una prueba asíncrona falsa. URL de la solicitud: http://xxxxxx/v1/products
Respuesta #1
Veo dos casos para probar: cuando statusCode === 1 y cuando statusCode !== 1.
Para la primera prueba: simula tu backend para que devuelva una respuesta como un observable de objeto con una propiedad StatusCode, establecida en 1.
Deberías crear un espía de Jasmine para el método logout del objeto auth.
Luego, suscríbete al método typegetall() y verifica en esta suscripción si se ha llamado a logout.
Para la segunda prueba: simula tu backend para que devuelva una respuesta como un objeto observable con una propiedad StatusCode, establecida en 2 Y una propiedad StatusDescription como un arreglo de alarm, sin instanciar como Alarm todavía.
Luego, suscríbete a typegetall(), con los datos devueltos (tu arreglo de Alarm). En esta suscripción, puedes probar la longitud y, para cada elemento, si es una instancia de Alarm.
Consulta la documentación oficial de pruebas para ver cómo crear tu respuesta simulada.
Para el primero :
it('should call logout when statusCode is equal to 1', () =>
{
alarmService = TestBed.get(AlarmService);
authService = TestBed.get(AuthService);
/* Put your mock response here, an observable of object with StatusCode set to 1 */
spyOn(authService, 'logout');
alarmService.typegetall().subscribe(() => {
expect(authService.logout).toHaveBeenCalledTimes(1);
});
}
Para el segundo :
it('should return an array Alarm when statusCode is equal to 2', () =>
{
alarmService = TestBed.get(AlarmService);
authService = TestBed.get(AuthService);
/* Put your mock response here, an observable of object with StatusCode set to 2 and StatusDescription set to an array of 3 alarm object*/
spyOn(authService, 'logout');
alarmService.typegetall().subscribe((alarms: Alarm[]) => {
expect(authService.logout).not.toHaveBeenCalled;
expect(alarms.length).toBe(3);
alarms.forEach(alarm => expect(jasmine.any(alarm instanceof Alarm)).toBeTruthy());
/*
Other expectations to check object properties values, such as :
expect(alarms[0].aProperty).toBe(...);
*/
});
}
Para probar errores, agregue el operador catchError de rxjs en su servicio (aprenda más aquí):
public typegetall(): Observable<Alarm[]> {
...
return this.http.get(Api.getUrl(Api.URLS.typegetall), {
headers: headers
})
.map((response: Response) => {
let res = response.json();
if (res.StatusCode === 1) {
this.auth.logout();
} else {
return res.StatusDescription.map(alarm => {
return new Alarm(alarm);
});
}
})
.catchError(error => of(`An error occured: ${error}`));
}
y pruébalo así :
it('should get an error', () =>
{
alarmService = TestBed.get(AlarmService);
/* Create your mock response error here, an observable created with '_throw' and return a value (ex: 'shit, error !') */
alarmService.typegetall().subscribe(error => expect(error).toBe('shit, error !'));
}
