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.
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