Las pruebas unitarias son una parte esencial del desarrollo de software, ya que permiten verificar que las unidades individuales de código (como funciones, métodos o clases) funcionan correctamente. En Angular, las pruebas unitarias se realizan utilizando herramientas como Jasmine y Karma.
Objetivos de esta sección
- Comprender la importancia de las pruebas unitarias.
- Configurar el entorno de pruebas en Angular.
- Escribir y ejecutar pruebas unitarias básicas.
- Utilizar
TestBed
para configurar y probar componentes y servicios.
¿Qué son las Pruebas Unitarias?
Las pruebas unitarias son pruebas automatizadas que verifican el comportamiento de una pequeña parte del código, generalmente una función o un método. Estas pruebas ayudan a:
- Detectar errores en etapas tempranas del desarrollo.
- Facilitar el mantenimiento del código.
- Asegurar que los cambios en el código no introduzcan nuevos errores.
Configuración del Entorno de Pruebas
Angular CLI viene preconfigurado con Jasmine y Karma para realizar pruebas unitarias. Jasmine es un framework de pruebas para JavaScript, mientras que Karma es un ejecutor de pruebas que permite ejecutar las pruebas en diferentes navegadores.
Instalación de Dependencias
Si has creado tu proyecto Angular con Angular CLI, las dependencias necesarias para las pruebas unitarias ya están instaladas. Si no, puedes instalarlas con los siguientes comandos:
npm install --save-dev jasmine-core karma karma-chrome-launcher karma-jasmine karma-jasmine-html-reporter
Estructura de Archivos de Pruebas
Por convención, los archivos de pruebas en Angular tienen la extensión .spec.ts
. Estos archivos se colocan junto a los archivos de código que están probando. Por ejemplo, si tienes un componente app.component.ts
, su archivo de prueba sería app.component.spec.ts
.
Escribiendo una Prueba Unitaria Básica
Vamos a escribir una prueba unitaria básica para una función simple. Supongamos que tenemos una función sum
en un archivo math.ts
:
El archivo de prueba para esta función sería math.spec.ts
:
// math.spec.ts import { sum } from './math'; describe('sum', () => { it('should return the sum of two numbers', () => { expect(sum(1, 2)).toBe(3); }); it('should return a negative number if the sum is negative', () => { expect(sum(-1, -2)).toBe(-3); }); });
Explicación del Código
describe
: Define un grupo de pruebas relacionadas.it
: Define una prueba individual.expect
: Realiza una afirmación sobre el resultado de la función.
Probando Componentes con TestBed
TestBed
es una utilidad de Angular que permite configurar y probar componentes y servicios en un entorno de pruebas.
Ejemplo de Prueba de Componente
Supongamos que tenemos un componente app.component.ts
:
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: '<h1>{{title}}</h1>' }) export class AppComponent { title = 'Hello Angular'; }
El archivo de prueba para este componente sería app.component.spec.ts
:
// app.component.spec.ts import { TestBed, ComponentFixture } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { let component: AppComponent; let fixture: ComponentFixture<AppComponent>; beforeEach(() => { TestBed.configureTestingModule({ declarations: [AppComponent] }).compileComponents(); fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; }); it('should create the component', () => { expect(component).toBeTruthy(); }); it(`should have as title 'Hello Angular'`, () => { expect(component.title).toEqual('Hello Angular'); }); it('should render title in a h1 tag', () => { fixture.detectChanges(); const compiled = fixture.nativeElement; expect(compiled.querySelector('h1').textContent).toContain('Hello Angular'); }); });
Explicación del Código
TestBed.configureTestingModule
: Configura un módulo de pruebas con los componentes necesarios.TestBed.createComponent
: Crea una instancia del componente para pruebas.fixture.detectChanges()
: Detecta cambios y actualiza la vista del componente.
Ejercicio Práctico
Ejercicio
Crea un componente greeting.component.ts
que tenga una propiedad greeting
y un método getGreeting()
. Escribe pruebas unitarias para verificar que la propiedad y el método funcionan correctamente.
// greeting.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-greeting', template: '<p>{{greeting}}</p>' }) export class GreetingComponent { greeting: string = 'Hello, World!'; getGreeting(): string { return this.greeting; } }
Solución
// greeting.component.spec.ts import { TestBed, ComponentFixture } from '@angular/core/testing'; import { GreetingComponent } from './greeting.component'; describe('GreetingComponent', () => { let component: GreetingComponent; let fixture: ComponentFixture<GreetingComponent>; beforeEach(() => { TestBed.configureTestingModule({ declarations: [GreetingComponent] }).compileComponents(); fixture = TestBed.createComponent(GreetingComponent); component = fixture.componentInstance; }); it('should create the component', () => { expect(component).toBeTruthy(); }); it(`should have as greeting 'Hello, World!'`, () => { expect(component.greeting).toEqual('Hello, World!'); }); it('should return the greeting', () => { expect(component.getGreeting()).toEqual('Hello, World!'); }); it('should render greeting in a p tag', () => { fixture.detectChanges(); const compiled = fixture.nativeElement; expect(compiled.querySelector('p').textContent).toContain('Hello, World!'); }); });
Conclusión
En esta sección, hemos aprendido la importancia de las pruebas unitarias y cómo configurarlas en un proyecto Angular. Hemos escrito pruebas unitarias básicas para funciones y componentes utilizando Jasmine y TestBed. Las pruebas unitarias son una herramienta poderosa para asegurar la calidad y la estabilidad del código, y su uso es una práctica recomendada en el desarrollo de aplicaciones Angular.
En la siguiente sección, exploraremos cómo realizar pruebas de componentes en mayor detalle, incluyendo la interacción con servicios y la simulación de dependencias.
Curso de Angular 2+
Módulo 1: Introducción a Angular
- ¿Qué es Angular?
- Configuración del Entorno de Desarrollo
- Tu Primera Aplicación Angular
- Arquitectura de Angular
Módulo 2: Conceptos Básicos de TypeScript
- Introducción a TypeScript
- Variables y Tipos de Datos en TypeScript
- Funciones y Funciones Flecha
- Clases e Interfaces
Módulo 3: Componentes y Plantillas
- Creación de Componentes
- Plantillas de Componentes
- Estilos de Componentes
- Interacción entre Componentes
Módulo 4: Directivas y Pipes
Módulo 5: Servicios e Inyección de Dependencias
- Introducción a los Servicios
- Creación y Uso de Servicios
- Inyección de Dependencias
- Inyectores Jerárquicos
Módulo 6: Enrutamiento y Navegación
Módulo 7: Formularios en Angular
- Formularios Basados en Plantillas
- Formularios Reactivos
- Validación de Formularios
- Formularios Dinámicos
Módulo 8: Cliente HTTP y Observables
- Introducción al Cliente HTTP
- Realizando Solicitudes HTTP
- Manejo de Respuestas HTTP
- Uso de Observables
Módulo 9: Gestión de Estado
- Introducción a la Gestión de Estado
- Uso de Servicios para la Gestión de Estado
- NgRx Store
- NgRx Effects