Inicio > Cursos > Node.js y Express > Testing con Jest y Supertest
Node.js y ExpressTesting y ProducciónLección 16 de 20

Testing con Jest y Supertest

Testing es fundamental para APIs en producción. Jest es el framework de testing más popular en el ecosistema JavaScript. Supertest permite hacer peticiones HTTP a tu app Express sin levantar un servidor real. Los mocks permiten aislar la lógica de negocio de la base de datos.

// npm install --save-dev jest supertest @jest/globals
// package.json: { "test": "jest --watch" }

const request = require('supertest');
const app = require('../src/app');
const { PrismaClient } = require('@prisma/client');

// Mock completo de Prisma para no tocar la BD real
jest.mock('@prisma/client', () => ({
  PrismaClient: jest.fn().mockImplementation(() => ({
    usuario: {
      create: jest.fn(),
      findMany: jest.fn(),
      findUnique: jest.fn(),
      update: jest.fn(),
      delete: jest.fn(),
    },
  })),
}));

const db = new PrismaClient();

describe('API Usuarios', () => {
  beforeEach(() => {
    jest.clearAllMocks(); // limpiar mocks entre tests
  });

  describe('GET /api/v1/usuarios', () => {
    test('devuelve lista de usuarios con meta', async () => {
      const usuariosMock = [
        { id: 1, nombre: 'Ana', email: 'ana@test.com' },
        { id: 2, nombre: 'Luis', email: 'luis@test.com' },
      ];

      db.usuario.findMany.mockResolvedValue(usuariosMock);

      const response = await request(app)
        .get('/api/v1/usuarios')
        .set('Authorization', 'Bearer token-valido-mock');

      expect(response.status).toBe(200);
      expect(response.body.data).toHaveLength(2);
      expect(response.body.meta).toBeDefined();
      expect(db.usuario.findMany).toHaveBeenCalledTimes(1);
    });
  });

  describe('POST /api/v1/usuarios', () => {
    test('crea usuario y devuelve 201', async () => {
      const nuevoUsuario = { nombre: 'Carlos', email: 'carlos@test.com', password: 'Pass123!' };
      db.usuario.create.mockResolvedValue({ id: 3, ...nuevoUsuario });

      const response = await request(app)
        .post('/api/v1/usuarios')
        .send(nuevoUsuario);

      expect(response.status).toBe(201);
      expect(response.body.email).toBe(nuevoUsuario.email);
    });

    test('retorna 400 si email es inválido', async () => {
      const response = await request(app)
        .post('/api/v1/usuarios')
        .send({ nombre: 'X', email: 'no-es-email', password: '123' });

      expect(response.status).toBe(400);
      expect(response.body.errores).toBeDefined();
      expect(db.usuario.create).not.toHaveBeenCalled();
    });
  });
});
ConsejoMockea la base de datos en los tests unitarios/integración. Los tests no deben depender de una BD real: son más rápidos, predecibles y se pueden correr sin infraestructura.
← Subida de ArchivosVariables de Entorno y Config →

Practica esta lección

Resuelve los ejercicios del curso de Node.js y Express en la app, gratis y con corrección automática.

Empezar a practicar