Configuración de Mock Service Worker para Pruebas en Visual Studio Code

Clase 15 de 20Curso de React Testing Library

Contenido del curso

Resumen

Cuando trabajas con APIs externas en tus pruebas, cualquier inestabilidad puede romper toda tu suite de tests. Mock Service Worker (MSW) resuelve este problema al interceptar peticiones HTTP directamente a nivel de red, sin tocar tu código de producción. A continuación se explica paso a paso cómo configurarlo en un proyecto con Vitest.

¿Qué es Mock Service Worker y por qué intercepta peticiones a nivel de red?

Mock Service Worker es una biblioteca que configura un Service Worker para escuchar tus peticiones HTTP. Un Service Worker es un script que el navegador ejecuta en segundo plano y actúa como un proxy entre tu aplicación y la red [0:10].

Sus características más relevantes son:

  • Funciona tanto en ambientes de pruebas como en ambientes de desarrollo.
  • Intercepta requests a nivel de red, lo que significa que tu aplicación no sabe que está hablando con un servidor simulado.
  • Mantiene el código de producción intacto, ya que no necesitas modificar las APIs reales.
  • Es compatible con API Rest, GraphQL y distintos protocolos de red [0:38].

¿Cómo se instala y estructura el proyecto con MSW?

Desde la terminal en Visual Studio Code, ejecutas el comando de instalación. El paquete se llama simplemente msw [1:10]:

bash yarn add -d msw

Una vez instalada la dependencia, se crea una carpeta llamada mocks dentro de src. Este naming sigue las buenas prácticas recomendadas por la propia librería [1:30].

¿Cómo se configuran los handlers?

Dentro de la carpeta mocks, se crea el archivo handlers.ts. Aquí defines los endpoints que quieres simular en tu ambiente de testing [1:42]:

typescript import { http, HttpResponse } from 'msw';

export const handlers = [ http.get('http://localhost:3001/orders', () => { return HttpResponse.json([ // Aquí va el arreglo de órdenes que tu componente espera ]); }), ];

La URL que colocas debe coincidir exactamente con la que tu aplicación consume. Si tu empresa tiene un dominio como platzi.com/api, esa es la ruta que debes especificar [2:20]. El callback retorna un HttpResponse.json con los datos simulados, en este caso copiados desde tu archivo db.json.

¿Cómo se levanta el servidor de MSW?

Se crea un segundo archivo en la carpeta mocks llamado server.ts. Aquí importas setupServer desde msw/node y le pasas los handlers para que el servidor sepa qué rutas debe responder [3:18]:

typescript import { setupServer } from 'msw/node'; import { handlers } from './handlers';

export const server = setupServer(...handlers);

¿Cómo se integra MSW con el archivo de configuración de tests?

El último paso es conectar el servidor con tu suite de pruebas. Para esto se modifica el archivo setup-test.ts ubicado en src [3:50]. Se importan tres funciones de Vitest que controlan el ciclo de vida de los tests:

  • beforeAll: se ejecuta una sola vez antes de todos los tests. Aquí llamas a server.listen() para que el servidor comience a escuchar peticiones [4:18].
  • afterEach: se ejecuta después de cada test individual. Aquí llamas a server.resetHandlers() para reiniciar el estado y evitar que un test corrompa a otro [4:40].
  • afterAll: se ejecuta una sola vez cuando terminan todos los tests. Aquí llamas a server.close() para cerrar el servidor [4:55].

typescript import { afterAll, afterEach, beforeAll } from 'vitest'; import { server } from './mocks/server';

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

La diferencia entre afterAll y afterEach es fundamental: afterEach garantiza que cada test tenga su caso aislado, mientras que afterAll solo ejecuta la limpieza final.

Después de guardar estos cambios, al correr el comando de tests todo sigue pasando correctamente [5:15]. Con esta configuración, el proyecto queda listo para crear tests que consuman endpoints simulados sin depender de APIs externas.

¿Ya has usado MSW en tus proyectos o prefieres otra estrategia para simular APIs? Comparte tu experiencia en los comentarios.