Pruebas maliciosas para GET
Clase 17 de 25 • Curso de Angular: Unit Testing para Servicios
Contenido del curso
Clase 17 de 25 • Curso de Angular: Unit Testing para Servicios
Contenido del curso
Cesar Elías Armendariz Ruano
Juan Luna
Jorge Luis Silva Medina
Danny Pacheco
Leandro Ariel Bustamante
José Israel Díaz Zapata
ISRAEL ARIAS
Jorge Luis Silva Medina
En las pruebas no es simplemente seguir el camino feliz o (happy path) sino tambien hacer las pruebas poniendo distintos parámetros.
Por ejemplo en el caso de pruebas en el product service se puede intentar mandar precios de la lista de productos en 0 o en negativa y verificar lo que debería devolver, e incluso hay que enviar parametros de limit y offset para verificar su funcionalidad.
product.service.spec.ts
it('should return product list width taxes', (doneFn) => { // Arrange const mockData: Product[] = [ { ...generateOneProduct(), price: 100, //100 * .19 = 19 }, { ...generateOneProduct(), price: 200, //200 * .19 = 38 }, { ...generateOneProduct(), price: 0, //0 * .19 = 0 }, { ...generateOneProduct(), price: -100, // = 0 }, ]; //Act productsService.getAll() .subscribe((data) => { //Assert expect(data.length).toEqual(mockData.length); expect(data[0].taxes).toEqual(19); expect(data[1].taxes).toEqual(38); expect(data[2].taxes).toEqual(0); expect(data[3].taxes).toEqual(0); doneFn(); }); //http config const url = `${environment.API_URL}/api/v1/products`; const req = httpController.expectOne(url); req.flush(mockData); httpController.verify(); }); it('should send query params width limit 10 offset 3', (doneFn) => { //Arrange const mockData: Product[] = generateManyProducts(3); const limit = 10; const offset = 3; //Act productsService.getAll(limit, offset) .subscribe((data) => { //Assert expect(data.length).toEqual(mockData.length); doneFn(); }); //http config const url = `${environment.API_URL}/api/v1/products?limit=${limit}&offset=${offset}`; const req = httpController.expectOne(url); req.flush(mockData); const params = req.request.params; expect(params.get('limit')).toEqual(`${limit}`); expect(params.get('offset')).toEqual(`${offset}`); httpController.verify(); }); });
si hay que cambiar algo en el código del servicio se lo puede hacer
product.service.ts
getAll(limit?: number, offset?: number): Observable<Product[]> { let params = new HttpParams(); if (limit && offset != null) { params = params.set('limit', limit); params = params.set('offset', offset); } return this.http.get<Product[]>(`${this.apiUrl}/products`, { params }) .pipe( retry(3), map(products => products.map(item => { return { ...item, taxes: item.price > 0 ? .19 * item.price : 0 } })) ); }
Pregunta tonta quizás, hemos generado 3 productos en la ultima prueba, generateManyProducts(3), pero mandamos un offset de 3 y un limit de 10 (productos), sin embargo la prueba no falla, cuando hacemos el expect(data.legnth).toEqual(mockData.length) ¡Que me maten si lo entiendo! ¿Alguien podría explicar esto? ¿No debería haberse hecho de esta otra forma para ser más coherente con lo que se está haciendo?, aunque de todas formas no falla, pongas lo que pongas...
const limit = 10; const offset = 3; const mockData: Product[] = generateManyProducts(limit);
Por eso es por lo que yo digo, ¿Quién testea las pruebas?..
gracias de antemano
Esta prueba que comentas puede aplicar cuando el total de productos es mayor al limite y ahí puedes probar si el limite se respeta.
Pero yo recomiendo que ese testing de esa lógica no debe estar en el FRONT debido a que el service no se encarga de limitar los registros, sino el BACK. Ese unit test debe estar en el BACK.
Lo que sucede en este caso es lo siguiente, recuerda que tu mockData es la simulación de la respuesta de tu backend después de aplicarle un query params, es decir, aquí no estamos validando la cantidad de registros que nos devuelve el backend después del query params y no se debería hacer porque es responsabilidad del backend validar que te retorne de forma correcta lo que envias en el query params, lo que hace esta prueba es verificar si el limit y el offset enviados son aceptables para realizar esta petición.
Me rindo intente de todo para que en mi projecto con angular 17 funcione el mocha reporter y nada :(
usa la versión 16. Si la 17 aún tiene cosas inestables
1. ng generate config karma
2. npm i karma-mocha-reporter --save-dev
3. karma.conf.js
4. plugins: [ require('karma-mocha-reporter') ],
5. change reporters: ['progress', 'kjhtml'] to this reporters: ['mocha', 'kjhtml'],
Agregue estas 2 pruebas
it('should send query params with limit 0 and offset 0', (doneFn) => { // Arange const mockData: Product[] = generateManyProducts(3); const limit = 0; const offset = 0; //Act service.getAll(limit, offset).subscribe((data) => { // Assert expect(data.length).toEqual(mockData.length); doneFn(); }); // http config const url = `${environment.API_URL}/api/v1/products`; const req = httpController.expectOne(url); req.flush(mockData); const param = req.request.params; expect(param.get('limit')).toBeNull(); expect(param.get('offset')).toBeNull(); httpController.verify(); });
it('should send query params with limit 1 and offset 0', (doneFn) => { // Arange const mockData: Product[] = generateManyProducts(3); const limit = 1; const offset = 0; //Act service.getAll(limit, offset).subscribe((data) => { // Assert expect(data.length).toEqual(mockData.length); doneFn(); }); // http config const url = `${environment.API_URL}/api/v1/products?limit=${limit}&offset=${offset}`; const req = httpController.expectOne(url); req.flush(mockData); const param = req.request.params; expect(param.get('limit')).toEqual(limit.toString()); expect(param.get('offset')).toEqual(offset.toString()); httpController.verify(); });