Pruebas con componentes anidados
Clase 10 de 20 • Curso de Angular: Unit Testing para Rutas
Contenido del curso
Clase 10 de 20 • Curso de Angular: Unit Testing para Rutas
Contenido del curso
Cesar Elías Armendariz Ruano
ntt data
Carlos Alejandro Hernández Mejía
todos los frameworks basan la renderización basado en componentes aninados, para poder hacer las pruebas desde Angular sería así
primero generamos los componentes que vamos a renderizar dentro del app.component.html
ng g c components/banner
ng g c components/footer
luego los ingresamos en el html de app.component
<app-banner></app-banner> <header class="container"> <h2>Angular Testing</h2> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Beatae illum saepe odio suscipit id sapiente consequuntur, ipsa laboriosam eius debitis quidem nisi quos veritatis eum soluta adipisci repellat commodi. Esse.</p> <nav> <ul> <li><a routerLink="/">Home</a></li> <li><a routerLink="/auth/register">Register</a></li> <li><a routerLink="/people">People</a></li> <li><a routerLink="/products">Products</a></li> <li><a routerLink="/others">others</a></li> <li><a routerLink="/pico-preview">Pico Preview</a></li> <li><a routerLink="/auth/login">Login</a></li> </ul> </nav> </header> <router-outlet></router-outlet> <app-footer></app-footer>
ahora podemos hacer las pruebas aunque se puede hacer de dos formas, la una ignarando la renderización de estos dos componentes o la otra creando substitutos vacios para que no generen errores ni advertencias.
app.component.spec.ts
@Component({ selector: 'app-banner' }) class BannerComponentStub {} @Component({ selector: 'app-footer' }) class FooterComponentStub {} fdescribe('AppComponent', () => { let fixture: ComponentFixture<AppComponent>; let component: AppComponent; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ RouterTestingModule ], declarations: [ AppComponent, RouterLinkDirectiveStub, BannerComponentStub, FooterComponentStub ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); });
Intento usar la forma que indicas para probar este componente:
import { Component, OnInit, ViewChild } from '@angular/core'; import { ModalComponent } from 'src/app/ui/components/modal/modal.component'; @Component({ selector: 'app-recharges', templateUrl: './recharges.component.html', styleUrls: ['./recharges.component.scss'] }) export class RechargesComponent implements OnInit { @ViewChild('modalDownloadReport') modalContainer!: ModalComponent; showModal = false; constructor() { } ngOnInit(): void { } toogleModal(event: boolean) { console.log(event); if(!event) { this.modalContainer.openModal(); } this.showModal = event; } }
En el .html solo tiene la inyeccion del componente ModalComponent:
<div class="mainContainer"> <app-modal #modalDownloadReport> </app-modal> <div class="oneSection"> 'Mi contenido...' </div> </div>
Me dice: Cannot find module 'src/app/ui/components/modal/modal.component'
Componentes anidados
Todos los frameworks basan la renderización en componentes de forma anidada, dónde cada uno de estos componentes puede llegar a tener su propia lógica, sus propias dependencias, etc.
Sí tenemos un componente padre con componentes hijos anidados y ejecutamos nuestras las pruebas del componente padre es posible que Angular no encuentre dichos elementos y te muestre un error con un texto similar a este:
Error: Template parse errors: 'app-my-component' is not a known element: 1. If 'app-my-component' is an Angular component, then verify that it is part of this module. 2. If 'app-my-component' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this
Existen 3 formas de resolver este error, las cuales se detallan a continuación:
Agregar dichos componentes al contexto de nuestro entorno de pruebas. Por ejemplo
```tsx beforeEach(async () => { await TestBed.configureTestingModule({ imports: [RouterTestingModule], declarations: [ AppComponent, **MyComponent**, // Other components, directives or pipes ], }).compileComponents(); fixture = TestBed.createComponent(AppComponent); app = fixture.componentInstance; }); ```
Pero, cómo dicho componentes anidados deberían tener sus propias pruebas unitarias, no es necesario que agreguemos estos componentes en las pruebas del componente padre, ya que esto podría afectar el rendimientos de nuestras pruebas e incluso, generarnos más dolores de cabeza.
Indicarle a nuestro entorno de pruebas que ignore los elementos desconocidos con la constante NO_ERRORS_SCHEMA proporcionada por @angular/core.
Por ejemplo
```tsx beforeEach(async () => { await TestBed.configureTestingModule({ imports: [RouterTestingModule], declarations: [AppComponent], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); fixture = TestBed.createComponent(AppComponent); app = fixture.componentInstance; }); ```
Crear un componente sustituto que posea el mismo selector que nuestros componentes anidados, pero no que no posea ninguna funcionalidad. Por ejemplo
```tsx // ComponentStub @Component({ selector: 'app-my', }) class MyComponentStub {} // Test environment beforeEach(async () => { await TestBed.configureTestingModule({ imports: [RouterTestingModule], declarations: [AppComponent, MyComponentStub], }).compileComponents(); fixture = TestBed.createComponent(AppComponent); app = fixture.componentInstance; }); ```