Pruebas Unitarias en Angular con Spector y AI

Clase 23 de 23Curso de Pruebas Unitarias en Angular

Resumen

La implementación de pruebas unitarias en Angular es fundamental para garantizar la calidad del código y la estabilidad de las aplicaciones. Utilizando herramientas como Jest y Spectator, podemos automatizar la verificación de componentes y servicios, asegurando que funcionen correctamente incluso después de realizar cambios. La inteligencia artificial también puede ser una gran aliada en este proceso, aunque requiere de nuestra guía y experiencia para obtener resultados óptimos.

¿Cómo completar las pruebas de un componente con múltiples dependencias?

Cuando trabajamos con componentes Angular que tienen múltiples inyecciones de dependencias, es importante asegurarnos de que todas ellas estén correctamente configuradas en nuestras pruebas. En el caso del componente ProductDetail, ya habíamos abordado la inyección más compleja (ProductService), pero aún quedaban pendientes otras como Cart y MetaTagService.

Para estas dependencias adicionales, podemos utilizar el enfoque de MockProvider que nos proporciona Spectator. A diferencia del caso más complejo donde necesitábamos configurar valores iniciales específicos, para servicios más simples podemos aprovechar las capacidades de mocking por defecto:

// Ejemplo de MockProvider para Cart
providers: [
  MockProvider(Cart)
]

Este enfoque es mucho más sencillo cuando solo necesitamos espiar funciones sin configurar comportamientos específicos. El MockProvider por defecto ya nos proporciona esta funcionalidad, lo que simplifica considerablemente nuestro código de prueba.

¿Cómo probar la funcionalidad de "añadir al carrito"?

Para probar la funcionalidad de añadir productos al carrito, necesitamos verificar que al hacer clic en el botón correspondiente, se ejecute el método adecuado del servicio. No es necesario probar que el producto realmente se agregue al carrito, ya que esa es responsabilidad del servicio Cart y debería probarse por separado.

Primero, añadimos un atributo data-testid al botón para facilitar su selección:

it('debería agregar un producto', () => {
  const cartService = spectator.inject(Cart);
  const button = spectator.query(byTestId('add-to-cart')) as HTMLButtonElement;
  
  spectator.click(button);
  
  expect(cartService.addToCart).toHaveBeenCalledWith(mockProduct);
});

En esta prueba:

  1. Obtenemos una referencia al servicio Cart mediante inyección
  2. Seleccionamos el botón usando el atributo data-testid
  3. Simulamos un clic en el botón
  4. Verificamos que el método addToCart del servicio haya sido llamado con el producto correcto

Es importante destacar que Spectator maneja automáticamente la detección de cambios después del clic, por lo que no necesitamos invocarla manualmente.

¿Cuáles son las mejores prácticas para escribir pruebas en Angular?

A lo largo del curso, hemos visto varias prácticas recomendadas para escribir pruebas efectivas en Angular:

  • Usar data-testid para seleccionar elementos: Esto hace que nuestras pruebas sean más robustas ante cambios en la estructura del DOM.

  • Reutilizar servicios inyectados: Es mejor obtener los servicios una vez y reutilizarlos en diferentes pruebas, en lugar de inyectarlos repetidamente.

  • Enfocarse en responsabilidades específicas: Cada componente o servicio debe probarse según sus propias responsabilidades, sin intentar verificar el comportamiento de sus dependencias.

  • Aprovechar las capacidades de Spectator: Esta biblioteca nos ahorra mucho código repetitivo y simplifica la escritura de pruebas.

  • Buscar una cobertura de al menos 80%: Este es un buen objetivo para asegurar que la mayoría del código está siendo verificado.

¿Cómo aprovechar la IA para escribir pruebas?

La inteligencia artificial puede ser una gran aliada para escribir pruebas unitarias, pero requiere de contexto y buenos ejemplos para generar código útil. Durante el curso, vimos que la IA a veces puede proponer casos innecesarios o utilizar métodos inadecuados.

Para aprovechar al máximo la IA en la escritura de pruebas:

  • Proporciona ejemplos claros y bien estructurados
  • Revisa y ajusta el código generado según tu experiencia
  • Guía a la IA especificando claramente lo que quieres probar
  • Utiliza la IA como complemento, no como reemplazo de tu conocimiento

Las pruebas unitarias son una de las áreas donde la delegación a la IA tiene más sentido, ya que los modelos de lenguaje pueden comprender el código y su propósito. Sin embargo, tu experiencia sigue siendo crucial para identificar dónde y cómo aplicar estas pruebas efectivamente.

El testing en Angular, combinado con herramientas como Jest, Spectator y la asistencia de IA, nos permite crear aplicaciones más robustas y mantenibles. Aunque Jest aún no está completamente soportado por el equipo de Angular, hemos visto cómo configurarlo adecuadamente en nuestros proyectos, y también podríamos utilizar alternativas como Jasmine o Vitest según nuestras preferencias.

Las pruebas unitarias son una inversión que paga dividendos a largo plazo, asegurando que nuestras aplicaciones sigan funcionando correctamente a medida que evolucionan. ¿Has implementado pruebas unitarias en tus proyectos Angular? Comparte tu experiencia en los comentarios.