Al finalizar este tutorial el estudiante estará en capacidad de desarrollar pruebas de integración para una aplicación Angular.
La prueba de integración del componente PostListComponent. La aplicación de ejemplo contiene una serie de "Posts" y por cada uno se cuenta con un botón "Like" y otro "Dislike". Dentro de cada botón está el número de veces que los usuarios han seleccionado Like o Dislike. La Figura 1 muestra la aplicación en ejecución.
Figura 1. Aplicación en ejecución |
Es necesario que conozca:
La prueba de integración la haremos con el componente PostListComponent. Este componente tiene un atributo posts
que es un arreglo de Post
. En el constructor se define un servicio postService
que será el encargado de traer desde una url el listado de posts.
import { Component, OnInit } from '@angular/core';
import { PostService } from '../post.service';
import { Post } from '../post';
@Component({
selector: 'app-post-list',
templateUrl: './post-list.component.html',
styleUrls: ['./post-list.component.css']
})
export class PostListComponent implements OnInit {
posts: Post[];
constructor(private postService: PostService) { }
ngOnInit() {
this.postService.getPosts().subscribe(posts => {
this.posts = posts;
})
}
}
En este componente vamos a realizar dos pruebas de integración.
La primera es comprobar la existencia de un párrafo de primer nivel con el texto "List of posts
".
La segunda es comprobar la existencia de un div con un el texto "Post 1". Para esto, y con el fin de no depender del servicio, vamos a crear un nuevo post directamente en la prueba.
La especificación de las pruebas la haremos en el archivo post-list.component.spec.ts el cual debe tener el siguiente código base:
/* tslint:disable:no-unused-variable */
import { HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LikeComponent } from 'src/app/like/like.component';
import { PostListComponent } from './post-list.component';
describe('PostListComponent', () => {
let component: PostListComponent;
let fixture: ComponentFixture<PostListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule],
declarations: [PostListComponent, LikeComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PostListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Antes de cada test debemos crear un Post con unos valores iniciales, detectar los cambios en el DOM y guardarlos en una variable. Para esto definimos, en el bloque describe una variable debug de tipo DebugElement, e importamos la librería: import { DebugElement } from '@angular/core';
describe('PostListComponent', () => {
let component: PostListComponent;
let fixture: ComponentFixture<PostListComponent>;
let debug: DebugElement;
...
Luego modificamos el método beforeEach así:
beforeEach(() => {
fixture = TestBed.createComponent(PostListComponent);
component = fixture.componentInstance;
component.posts = [new Post(1, "Post 1", "Content of post 1")];
fixture.detectChanges();
debug = fixture.debugElement;
});
Luego creamos la prueba que analiza el DOM y verifica que exista un título de primer nivel con el texto List of posts.
it("Should have an h1 tag", () => {
expect(debug.query(By.css("h1")).nativeElement.innerText).toBe("List of posts");
})
La siguiente prueba verifica que exista un div y que ese div contenga el texto Post 1.
it("Should have a div tag", () => {
const tag = debug.query(By.css("div")).nativeElement.children;
expect(tag.length).toBe(1);
expect(tag[0].innerText).toContain("Post 1")
})
Para la ejecución de la prueba, al igual que en las pruebas unitarias se debe correr el comando ng test
.
En la ventana de navegador que se despliega podemos ver el post que se ha creado.
El siguiente es el código completo de la prueba:
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from "@angular/platform-browser";
import { PostListComponent } from './post-list.component';
import { LikeComponent } from '../../like/like.component';
import { HttpClientModule } from '@angular/common/http';
import { DebugElement } from '@angular/core';
import { Post } from '../post';
import { Observable, of } from 'rxjs';
describe('PostListComponent', () => {
let component: PostListComponent;
let fixture: ComponentFixture<PostListComponent>;
let debug: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule],
declarations: [PostListComponent, LikeComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PostListComponent);
component = fixture.componentInstance;
component.posts = [new Post(1, "Post 1", "Content of post 1")];
fixture.detectChanges();
debug = fixture.debugElement;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it("Should have an h1 tag", () => {
expect(debug.query(By.css("h1")).nativeElement.innerText).toBe("List of posts");
})
it("Should have a div tag", () => {
const tag = debug.query(By.css("div")).nativeElement.children;
expect(tag.length).toBe(1);
expect(tag[0].innerText).toContain("Post 1")
})
});