Volver a la página principal
viernes 11 octubre 2024
9

Cómo hacer tests con Jasmine en Node.js

Jasmine es un framework de pruebas para JavaScript que permite escribir tests de forma clara y legible. Aunque inicialmente se diseñó para trabajar en el entorno del navegador, su implementación también es compatible con Node.js. Jasmine se destaca por su sintaxis descriptiva, lo que lo hace perfecto para realizar pruebas unitarias en tus proyectos. En este artículo, te mostraré cómo configurar y ejecutar tests con Jasmine en un entorno Node.js.

¿Qué es Jasmine?

Jasmine es un framework de testing que sigue el paradigma de Behaviour Driven Development (BDD), un enfoque donde las pruebas se diseñan para describir el comportamiento de las funcionalidades del código. Este enfoque facilita la creación de pruebas que no solo verifiquen que el código funciona, sino que además permitan entender de manera intuitiva qué hace cada componente.

Algunas características de Jasmine son:

  • No depende de navegadores ni de otros frameworks.
  • Permite la creación de test suites y especificaciones.
  • Cuenta con un soporte integrado para espiar (spies) funciones y métodos.
  • Ofrece un entorno de pruebas asíncronas fácil de manejar.

Instalación de Jasmine en Node.js

Antes de empezar con las pruebas, es necesario instalar Jasmine en tu proyecto Node.js. Puedes hacerlo utilizando npm o yarn. Asegúrate de tener Node.js instalado en tu sistema.

Paso 1: Crear un proyecto de Node.js

Si aún no tienes un proyecto de Node.js, crea uno utilizando el siguiente comando:

mkdir mi-proyecto
cd mi-proyecto
npm init -y

Este comando inicializa un nuevo proyecto de Node.js con un archivo package.json básico.

Paso 2: Instalar Jasmine

Instala Jasmine como una dependencia de desarrollo en tu proyecto:

npm install jasmine --save-dev

Esto agregará Jasmine a tu proyecto y permitirá utilizarlo para realizar pruebas unitarias.

Paso 3: Configurar Jasmine

Una vez que hayas instalado Jasmine, debes configurarlo para tu entorno de Node.js. Ejecuta el siguiente comando:

npx jasmine init

Este comando creará una carpeta llamada spec en tu proyecto y generará un archivo spec/support/jasmine.json con la configuración predeterminada de Jasmine.

Estructura de carpetas recomendada

Se recomienda utilizar la siguiente estructura de carpetas para mantener tus pruebas organizadas:

mi-proyecto/
├── src/
│   └── calculadora.js
├── spec/
│   └── calculadoraSpec.js
└── package.json

Aquí, src contiene el código fuente de tu proyecto, y spec almacena los archivos de pruebas.

Escribiendo tu primer test con Jasmine

Supongamos que tienes un archivo calculadora.js en la carpeta src con el siguiente contenido:

// src/calculadora.js
function sumar(a, b) {
  return a + b;
}

function restar(a, b) {
  return a - b;
}

module.exports = { sumar, restar };

Ahora, vamos a crear un archivo de prueba llamado calculadoraSpec.js en la carpeta spec:

// spec/calculadoraSpec.js
const calculadora = require('../src/calculadora');

describe("Pruebas de la calculadora", () => {
  it("Debería sumar dos números correctamente", () => {
    expect(calculadora.sumar(2, 3)).toBe(5);
  });

  it("Debería restar dos números correctamente", () => {
    expect(calculadora.restar(5, 3)).toBe(2);
  });
});

Explicación de la estructura del test

  • describe(): Agrupa un conjunto de especificaciones relacionadas. En este caso, las pruebas de la calculadora.
  • it(): Define una especificación o caso de prueba. Cada especificación contiene una descripción y una función que realiza la verificación.
  • expect(): La función que realiza la verificación de que el valor obtenido (calculadora.sumar(2, 3)) es igual al valor esperado (5).
  • toBe(): Es un matcher de Jasmine que compara el valor real con el valor esperado.

Ejecutar los tests

Para ejecutar las pruebas, utiliza el siguiente comando:

npx jasmine

Si todo está configurado correctamente, verás una salida similar a esta en la terminal:

Started
..

2 specs, 0 failures
Finished in 0.007 seconds

Esto indica que ambos tests pasaron exitosamente.

Haciendo pruebas asíncronas en Jasmine

Node.js se destaca por su arquitectura basada en eventos y su capacidad de manejar operaciones asíncronas. Jasmine tiene soporte para pruebas asíncronas usando done o async/await. Veamos un ejemplo simple:

Supongamos que tienes un archivo calculadoraAsync.js con el siguiente contenido:

// src/calculadoraAsync.js
function sumarAsync(a, b) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(a + b), 100);
  });
}

module.exports = { sumarAsync };

Y ahora, crea un archivo de prueba para calculadoraAsync.js:

// spec/calculadoraAsyncSpec.js
const calculadoraAsync = require('../src/calculadoraAsync');

describe("Pruebas asíncronas de la calculadora", () => {
  it("Debería sumar dos números de forma asíncrona", async () => {
    const resultado = await calculadoraAsync.sumarAsync(2, 3);
    expect(resultado).toBe(5);
  });
});

Explicación

  • Aquí utilizamos la sintaxis async/await para esperar el resultado de la operación asíncrona. Jasmine automáticamente espera que la función async complete su ejecución antes de evaluar la expectativa.

Espías en Jasmine (Spies)

Los espías (spies) son una característica avanzada de Jasmine que permite interceptar las llamadas a funciones y monitorear cómo se utilizan. Se pueden utilizar para:

  • Verificar si una función fue llamada y con qué argumentos.
  • Sustituir temporalmente una implementación.
  • Contar cuántas veces fue llamada una función.

Ejemplo de uso de un espía

Supongamos que tenemos el siguiente código en operaciones.js:

// src/operaciones.js
function multiplicar(a, b) {
  return a * b;
}

function calcular(a, b, callback) {
  return callback(a, b);
}

module.exports = { multiplicar, calcular };

Vamos a crear un archivo de prueba operacionesSpec.js:

// spec/operacionesSpec.js
const operaciones = require('../src/operaciones');

describe("Espías en Jasmine", () => {
  it("Debería llamar a la función de multiplicación con los argumentos correctos", () => {
    const spyMultiplicar = spyOn(operaciones, 'multiplicar').and.callThrough();

    operaciones.calcular(3, 4, operaciones.multiplicar);

    expect(spyMultiplicar).toHaveBeenCalled();
    expect(spyMultiplicar).toHaveBeenCalledWith(3, 4);
  });
});

Explicación

  • spyOn(objeto, 'nombreFunción'): Crea un espía en la función especificada.
  • .and.callThrough(): Permite que la función original se ejecute. Si quieres que el espía no ejecute la función original, puedes utilizar .and.returnValue(valor) para devolver un valor falso.
  • toHaveBeenCalled(): Verifica si el espía fue llamado.
  • toHaveBeenCalledWith(arg1, arg2, ...): Verifica si el espía fue llamado con los argumentos específicos.

Conclusión

Jasmine es una herramienta poderosa para realizar pruebas unitarias en proyectos de Node.js. Con su sintaxis clara y enfoque BDD, facilita la escritura de tests que describen el comportamiento del código de manera comprensible. Además, Jasmine ofrece características avanzadas como espías y soporte para pruebas asíncronas, lo que lo hace ideal para aplicaciones modernas.

Con este tutorial, ya deberías tener una comprensión sólida de cómo empezar a usar Jasmine en tus proyectos de Node.js. ¡Ahora es momento de que pongas manos a la obra y comiences a probar tu propio código!

Si te interesa profundizar en el tema, considera explorar otras funciones avanzadas de Jasmine como beforeEach, afterEach y los diferentes *matchers* disponibles para hacer tus pruebas más robustas.

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer