Cómo sobre-cargar MatIcon para usar íconos personalizados en pruebas en Angular

Aprende a reparar el problema de íconos personalizados de MatIcon en pruebas unitarias en Angular de forma fácil
Angular

En estos días estoy corrigiendo un montón de pruebas que fallaron debido a una actualización de Angular 16, y entre las reparaciones que tenemos que hacer es sustituir un extraño formato que se vino usando de NgMock para cambiarlo al estándar, en este cambio y la actualización varias pruebas empezaron a tronar como palomita por culpa de mat-icon (proveniente de Angular Material)

¿Cuál era el error?, bueno tenemos un diccionario personalizado de íconos, es decir, metemos íconos usando el parámetro de svgIcon y le pasamos ahí nuestros íconos personalizados en SVG, sin embargo en las pruebas unitarias como comento, empezó a fallar todo, en internet dicen N mil soluciones a cosas sin sentido, e incluso alguien da una solución con un beforeEach(inject([... pero es pésima la solución porque no resuelve nada.

Se me ocurrió, ¿por qué no sobre-escribir el módulo que proviene desde un SharedModule y ahí forzar un componente que lo sobre-escriba/mockee… así que así llegué a la solución, para esto hay que agregar en el beforeEach donde ponemos nuestro TestBed.configureTestingModule un poquito más arriba (o abajo en realidad no hay tanta variación según entiendo pero yo preferí ponerla antes y con un await) de la siguiente manera:

beforeEach(async () => {
   await TestBed.overrideModule(SharedModule, {
      remove: {
        imports: [MatIconModule]
      },
      add: {
        declarations: [MockMatIcon]
      }
   });
   await TestBed.configureTestingModule({ });
});

Y este MockMatIcon es un componente dummy que se agrega fuera del Describe de la siguiente forma:

@Component({
  template: '',
  selector: 'mat-icon'
})
class MockMatIcon {}

Y eso es todo, así de fácil y sencillo podemos cargar todos los componentes personalizados sin ver los errores en consola cuando hacemos pruebas unitarias.

(Paréntesis, no te olvides de agregar el MockMatIcon a las declarations de tu TestBed.configureTestingModule)

Ojo, esto no permitirá mostrar los elementos en el componente general, así que si probarán las vistas, hagan pruebas a través del mismo selector y nada más, no tiene sentido (a mi parecer) probar el contenido interno del componente así… (o ni si quiera sé si se pueda).

Espero te sirva este tutorial y no sufras como yo perdiendo horas en internet tratando de dar con la solución.

¡Hasta el próximo tutorial!

¿Cuál es tu reacción?
+1
0
+1
0
+1
0
+1
0
+1
0
Total
0
Shares
Publicación anterior
Angular

Posible reparación: inject() must be called from an injection en Angular

Publicaciones Relacionadas