DevPath · Aprende a programar ESPTEN

Testing y Node avanzado

Testing del backend

Por qué probar el backend

Un test automático es código que ejecuta tu código y falla si el comportamiento no es el esperado. En el backend nos protege de romper endpoints, reglas de negocio o contratos de datos al refactorizar.

Se distinguen dos grandes familias:

Aislar con dobles de prueba (mocks)

Para probar una unidad sin sus dependencias reales se usan dobles: objetos falsos que sustituyen a una dependencia (la base de datos, un servicio externo). Un mock o espía además registra cómo se le llamó, para poder afirmar sobre ello después.

// Servicio que depende de un "repositorio" (acceso a datos).
function registrarUsuario(repo, nombre) {
  return repo.guardar({ nombre, creado: true });
}

// En el test, le pasamos un repo FALSO que espía las llamadas.
const llamadas = [];
const repoMock = {
  guardar(usuario) { llamadas.push(usuario); return { id: 1, ...usuario }; },
};

const r = registrarUsuario(repoMock, "Ana");
// Verificamos comportamiento (no implementación interna):
//   - se llamó a guardar exactamente una vez
//   - con el nombre correcto
//   - y devolvimos lo que el repo devolvió

La clave del mock: comprobar que se llamó correctamente (cuántas veces, con qué argumentos) sin ejecutar la dependencia real.

Probar endpoints con supertest

Para las pruebas de integración de un servidor HTTP, la librería supertest lanza la app sobre un puerto efímero y deja escribir aserciones sobre la respuesta:

import request from "supertest";
import { app } from "./app.js";

await request(app)
  .get("/usuarios/1")
  .expect(200)
  .expect((res) => {
    if (res.body.nombre !== "Ana") throw new Error("nombre incorrecto");
  });

supertest se encarga de arrancar y cerrar el servidor; tú solo describes la petición (.get, .post, .send(...)) y lo que esperas (.expect(...)).

TDD (Test-Driven Development)

El desarrollo guiado por pruebas invierte el orden habitual en un ciclo corto:

  1. Rojo: escribe primero un test que describe el comportamiento deseado. Falla (aún no existe el código).
  2. Verde: escribe el mínimo código para que el test pase.
  3. Refactor: limpia el código con la red de seguridad del test en verde.

TDD empuja a diseñar funciones pequeñas y testeables, y deja una suite de pruebas como subproducto natural.

Ejemplos

Un espía simple: registrar las llamadas en un array

function notificar(servicio, mensaje) {
  servicio.enviar(mensaje);
}

const llamadas = [];
const servicioMock = { enviar: (m) => llamadas.push(m) };

notificar(servicioMock, "Hola");
notificar(servicioMock, "Adiós");

console.log(llamadas.length);   // 2 -> se llamó dos veces
console.log(llamadas[0]);       // "Hola" -> con el argumento correcto
Pon esto en práctica

DevPath es un curso práctico: aquí lees la teoría; en la app la pones en práctica con ejercicios que se ejecutan de verdad, sin conexión.

Empezar gratis en la app →
Asincronía avanzada y streams →