Mocks MSW - patrones de validación y depuración


🎯 Objetivo

Esta nota reúne estrategias, patrones y técnicas de depuración para entornos que usan MSW (Mock Service Worker), facilitando el diagnóstico de fallos, la verificación de llamadas y la observación de comportamiento de red en entornos locales y CI.


🧠 Conceptos Clave

  • Validación de Mocks: Asegurar que los handlers realmente interceptan las peticiones esperadas.
  • Depuración Contextual: Usar logs, ctx y server.events para inspeccionar comportamiento.
  • Análisis de Flujo: Observar el orden y frecuencia de llamadas de red.
  • Detección de Errores Silenciosos: Configurar onUnhandledRequest como "error" para detectar endpoints no mockeados.
  • Reproducción Controlada: Emular errores HTTP o latencias sin depender del backend real.
  • Instrumentación: Registrar actividad de red y estados del mock server para trazabilidad.

🧩 Patrón 1 — Validación de Handlers Activos

Descripción

Asegura que los mocks cargados sean los correctos antes de ejecutar los tests.

Ejemplo

import { server } from '@/mocks/server';
import { handlers } from '@/mocks/handlers';

test('todos los handlers activos están registrados', () => {
	expect(server.listHandlers().length).toBe(handlers.length);
});

`

Consejo

Si server.listHandlers() devuelve menos handlers de los esperados, revisa si se están sobrescribiendo en algún beforeEach().


🧩 Patrón 2 — Logs Detallados de Request/Response

Descripción

Registrar la información completa de las solicitudes interceptadas y sus respuestas.

Ejemplo

import { server } from '@/mocks/server';

server.events.on('request:start', (req) => {
	console.log(`🟢 [MSW] → ${req.method} ${req.url.href}`);
});

server.events.on('response:mocked', (res, req) => {
	console.log(`🧩 [MSW] Mock response for ${req.url.href}:`, res.status);
});

🧭 Ideal para entornos CI/CD donde los logs de consola pueden ayudar a identificar mocks fallidos.


🧩 Patrón 3 — Depuración de Handlers Dinámicos

Descripción

Sobrescribir un handler temporalmente dentro de un test sin afectar al resto.

Ejemplo

import { rest } from 'msw';
import { server } from '@/mocks/server';

test('mock temporal de error 500', async () => {
	server.use(
		rest.get('/api/user', (_, res, ctx) =>
			res(ctx.status(500), ctx.json({ error: 'Server down' }))
		)
	);
	const response = await fetch('/api/user');
	expect(response.status).toBe(500);
});

🧠 Usa este patrón cuando quieras simular fallos o respuestas lentas (ctx.delay()).


🧩 Patrón 4 — Fallback de Handlers

Descripción

Define un mock por defecto para endpoints desconocidos.

Ejemplo

import { server } from '@/mocks/server';

beforeAll(() => {
	server.listen({
		onUnhandledRequest: (req) => {
			console.warn(`⚠️ Unhandled request: ${req.method} ${req.url.href}`);
		},
	});
});

💡 Esto evita falsos positivos y te alerta si un endpoint no está cubierto por un handler.


🧩 Patrón 5 — Visualización de Tráfico Mockeado

Descripción

Monitoriza la actividad de MSW con herramientas externas o dashboards personalizados.

Ejemplo Integración

server.events.on('request:start', (req) => {
	window.__MOCK_TRAFFIC__ = window.__MOCK_TRAFFIC__ || [];
	window.__MOCK_TRAFFIC__.push({
		url: req.url.href,
		method: req.method,
		timestamp: Date.now(),
	});
});

👁️ Puedes inspeccionar window.__MOCK_TRAFFIC__ desde la consola del navegador para ver todas las llamadas interceptadas.


🧩 Patrón 6 — Debugging Integrado con ctx

Descripción

Usa ctx para inyectar headers, tiempos y logs durante la simulación.

Ejemplo

rest.get('/api/products', (req, res, ctx) => {
	console.info('Fetching products mock:', req.url.searchParams);
	return res(
		ctx.status(200),
		ctx.set('x-debug', 'true'),
		ctx.delay(300),
		ctx.json([{ id: 1, name: 'Mocked Vase' }])
	);
});

📦 Ideal para validar cómo maneja tu frontend retrasos o cabeceras específicas.


🧩 Patrón 7 — Validación en CI/CD

Descripción

Detecta errores de mocks directamente en pipelines.

Ejemplo (Jest + GitHub Actions)

test('no hay peticiones sin mock en CI', async () => {
	server.events.on('request:unhandled', (req) => {
		throw new Error(`Unhandled: ${req.method} ${req.url.href}`);
	});
	await runAppSimulation();
});

🧩 Esto evita fallos silenciosos cuando un test nuevo introduce endpoints sin cubrir.


🧩 Patrón 8 — Uso de afterAll y resetHandlers Correcto

Descripción

Garantiza limpieza total del entorno de mock tras cada test suite.

Ejemplo

import { server } from '@/mocks/server';

afterEach(() => server.resetHandlers());
afterAll(() => server.close());

🧹 Evita que un handler modificado persista y afecte otros tests.


🧩 Patrón 9 — Test de Performance con Mocks Activos

Descripción

Combina profiler con MSW para medir impacto del tráfico mockeado.

Ejemplo

import { startProfiler, stopProfiler } from '@/utils/profiler';

test('performance del flujo login', async () => {
	startProfiler();
	await fetch('/api/login', { method: 'POST' });
	const metrics = stopProfiler();
	expect(metrics.responseTime).toBeLessThan(100);
});

🧠 Esto permite validar no solo la respuesta funcional, sino también el tiempo de simulación.


🧩 Patrón 10 — Inspección en Navegador (DevTools)

Descripción

En modo browser, puedes activar window.msw para depurar desde consola:

window.msw.worker.printHandlers();

📘 Muestra todos los endpoints simulados y sus métodos.


🧩 Patrón 11 — Depuración Avanzada con Breakpoints

Descripción

Permite pausar la ejecución del handler para inspeccionar contexto.

Ejemplo

rest.get('/api/profile', (req, res, ctx) => {
	debugger; // pausa ejecución al interceptar
	return res(ctx.status(200), ctx.json({ user: 'debug-mode' }));
});

🪲 Ideal cuando no sabes si el mock se ejecuta realmente.


🔍 Diagnóstico Rápido

Síntoma Causa común Solución
Peticiones reales en tests server.listen() no llamado Añadir beforeAll() en setup
Mocks no actualizados Handlers no reseteados Usar server.resetHandlers()
Logs duplicados Setup repetido Verificar configuración global de Jest/Vitest
CI falla sin motivo Endpoint no mockeado Usar onUnhandledRequest: 'error'
Respuestas vacías JSON no devuelto Asegurar ctx.json() en handlers

🔗 Referencias