🇺🇸 EN
Frontend
·6 min read·↗·🇺🇸 EN

Cómo empezar con testing en Angular usando Jasmine

Portada principal del artículo: Cómo empezar con testing en Angular usando Jasmine

Trabajé durante varios meses con Jest y Vue, pero actualmente trabajo con Angular y el testing es parte de mi proceso de aprendizaje.

Voy a explicar un poco sobre Jasmine y cómo escribir pruebas para clases de TypeScript. Si encuentras algún error o algo que mejorar, puedes avisarme por Twitter a @danywalls.

El testing en Angular

Angular nació listo para ser testeable. Viene preparado con herramientas como Jasmine y Karma para ayudarnos a crear pruebas unitarias y de extremo a extremo (E2E).

El CLI de Angular nos proporciona la estructura base para generar y ejecutar estas pruebas. Además, Jasmine y Karma nos ayudan a correr los tests durante el desarrollo o en el proceso de compilación.

Pruebas unitarias

Una prueba unitaria sirve para verificar una pieza o unidad esencial de código, lo que significa que el test solo evalúa una única responsabilidad.

Las pruebas unitarias nos permiten probar funciones, clases, objetos y más.

Jasmine es el framework que utiliza Angular para escribir este tipo de pruebas.

Funciones de Jasmine

El framework Jasmine incluye varias funciones. No necesitas memorizar todas, solo entender las fundamentales como describe y expect.

describe ayuda a agrupar una serie de pruebas, es decir, una suite de pruebas. Recibe dos parámetros: una cadena de texto y una función callback.

describe("my group of invoice tests", () => {} );

La función it ayuda a definir una prueba específica. Es similar a describe, pero aquí es donde escribimos la prueba en sí.

it("the number should be positive", () => {});

La función expect se encarga de confirmar que el código funcione como esperamos, realizando las aserciones. En expect pasamos el valor que queremos comprobar, y la función comparadora (matcher) evalúa el resultado esperado.

Algunas de las funciones comparadoras más comunes son toBe(), toBeTruthy() o toEqual().

expect(true).toBeThruthy();

La convención para los archivos de pruebas unitarias es nombre-del-archivo.spec.ts. Por defecto, el CLI de Angular genera app.component.spec.ts, y puedes ejecutar las pruebas con el comando ng test.

Escribir una prueba unitaria básica con Jasmine

Es momento de poner en práctica lo aprendido escribiendo una pequeña prueba con describe para la clase Gif.

export class Gif {
  private _url: string;
  urlValidator = new RegExp(/^(ftp|http|https):\/\/[^ "]+$/);
  public get url(): string {
    return this._url;
  }
  public set url(v: string) {
    this._url = v;
  }
  public get isvalid(): boolean {
    return this.urlValidator.test(this.url);
  }
}

¡ESPERA UN MOMENTO!

Sé que el testing en Angular asusta a muchos desarrolladores, incluyéndome a mí. ¿Quieres entender las pruebas en Angular, desde lo básico hasta conceptos avanzados, con lo que realmente importa en proyectos reales?

Echa un vistazo a "Conscious Angular Testing" de Decoded Frontend: ¡ahora con un descuento especial!

El curso explica con claridad temas como TestBed, configuración de pruebas, lifecycle hooks y manejo de dependencias. Te enseña cómo escribir pruebas que no sean frágiles, trabajar con componentes standalone, content projection, pruebas con inyección de dependencias, servicios y componentes con dependencias.
Después de este curso, perdí el miedo a escribir pruebas en Angular.

¿Qué puedo probar?

  • Si las propiedades públicas url e isvalid tienen el valor esperado.
  • El comportamiento ante una URL inválida (que marque el gif como no válido).
  • Si se puede crear una instancia de la clase.
  • Si la URL se puede asignar correctamente.

¡Vamos a ello!

  1. Importa la clase Gif y usa describe para definir el grupo de pruebas.
import { Gif } from './gif';
describe('Gif Class tests', () => {
	
}
  1. Usando la función it, define la prueba para validar el constructor de la clase y usa expect para comprobar que no sea null.
import { Gif } from './gif';
describe('The Gif', () => {
  it('should to have a valid constructor', () => {
    const gif = new Gif();
    expect(gif).not.toBeNull();
  });
}

Ejecutamos nuestras pruebas con ng test desde la terminal.

Chrome 85.0.4183.121 (Windows 10): Executed 1 of 1 SUCCESS (0.035 secs / 0.01 secs)
TOTAL: 1 SUCCESS

Ahora agrego las pruebas restantes para las propiedades públicas.

import { Gif } from './gif';
describe('The Gif', () => {
  it('should to have a valid constructor', () => {
    const gif = new Gif();
    expect(gif).not.toBeNull();
  });
 
  it('should set the url', () => {
    const gif = new Gif();
    gif.url = 'http://google.com';
    expect(gif.url).not.toBeNull();
  });
 
  it('should be invalid gif for wrong url', () => {
    const gif = new Gif();
    gif.url = 'ht';
    expect(gif.isvalid).toBe(false);
  });
 
  it('should be valid gif for valid url', () => {
    const gif = new Gif();
    gif.url = 'http://www.google.com';
    expect(gif.isvalid).toBe(true);
  });
 
  it('should asign the url string', () => {
    const gif = new Gif();
    const expectedUrl = 'http://www.google.com';
    gif.url = expectedUrl;
    expect(gif.url).toEqual(expectedUrl);
  });
});

Luego ejecuta el comando ng test para ver los resultados.

Alt Text
Alt Text

Refactorizar las pruebas con beforeEach y afterEach

Si revisamos el código, se crea una instancia de Gif en cada prueba; este no es el mejor enfoque. Jasmine nos ofrece una solución para la inicialización de las pruebas con las funciones beforeEach() y afterEach().

La función beforeEach nos ayuda a ejecutar código antes de cada prueba. En este caso, declaramos una variable de tipo Gif y la inicializamos para cada test.

describe('The Gif', () => {
  let gif: Gif = null;
  beforeEach(() => {
    gif = new Gif();
  });
    ...

Lo mismo aplica para afterEach: asignamos la instancia de gif a null al finalizar cada prueba.

afterEach(() => {
    gif = null;
  });

El código final queda así:

import { Gif } from './gif';
describe('The Gif', () => {
  let gif: Gif = null;
  beforeEach(() => {
    gif = new Gif();
  });
  it('should to have a valid constructor', () => {
    expect(gif).not.toBeNull();
  });
 
  it('should set the url', () => {
    gif.url = 'http://google.com';
    expect(gif.url).not.toBeNull();
  });
 
  it('should be invalid for wrong url', () => {
    gif.url = 'ht';
    expect(gif.isvalid).toBe(false);
  });
 
  it('should be valid for valid url', () => {
    gif.url = 'http://www.google.com';
    expect(gif.isvalid).toBe(true);
  });
 
  it('should asign the url string', () => {
    const expectedUrl = 'http://www.google.com';
    gif.url = expectedUrl;
    expect(gif.url).toEqual(expectedUrl);
  });
  afterEach(() => {
    gif = null;
  });
});

Ejecuta las nuevas pruebas con el comando ng test desde tu terminal.

ng test
Alt Text
Alt Text

¡Listo!

Ahora puedes sentirte con más seguridad al escribir tus primeras pruebas con Jasmine en tus aplicaciones de Angular.

Parte de la serie Frontend

Modern frontend development — Angular, React, TypeScript, accessibility, and performance.

Ver serie completa

Artículos Relacionados

Compartir este artículo

Si esta guía te resultó útil, compártela con tu equipo o con otros desarrolladores.


Software real. Lecciones reales.

Comparto las lecciones que aprendí por las malas, para que puedas evitarlas o estar preparado cuando ocurran.

User avatar
User avatar
User avatar
User avatar
+13K

Únete a 13,800+ desarrolladores y lectores.

Cero spam. Cancela tu suscripción en cualquier momento.