React

Mock dell'API con MSW: rete finta, codice vero

MSW intercetta le richieste di rete e risponde con handler: il componente esegue il codice vero e il test non dipende da un server esterno.

In sintesi

  • MSW intercetta la rete: il componente usa fetch o axios veri.
  • onUnhandledRequest: error fa fallire le richieste non previste.
  • Gli handler restano fuori dal bundle di produzione.

MSW intercetta le richieste al livello di rete e risponde con handler: il componente esegue il suo codice vero, cambia solo il server.

Perché non mockare fetch

Sostituire fetch con una funzione finta lega il test all'implementazione: se il componente passa ad axios, il test si rompe. MSW intercetta la richiesta e restituisce una risposta HTTP completa.

Un handler

import { http, HttpResponse } from "msw";

export const handlers = [
  http.post("/api/login", async ({ request }) => {
    const { email } = await request.json();
    if (!email) return HttpResponse.json({ error: "email required" }, { status: 422 });
    return HttpResponse.json({ token: "test-token" });
  }),
];

L'handler risponde come il server: codice di stato, corpo JSON e ritardo se serve. Il test verifica il comportamento del componente davanti a una risposta reale, non a una promessa finta.

Collegarlo ai test

import { setupServer } from "msw/node";
import { handlers } from "./handlers";

const server = setupServer(...handlers);

beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

onUnhandledRequest: "error" è la parte che conta: una richiesta non prevista fa fallire il test invece di uscire in rete.

Installazione

npm i -D msw
npx msw init public/ --save

MSW è distribuito con licenza MIT. Il comando msw init copia il service worker in public e registra il percorso nel package.json.

Tre componenti che chiamano un'API: login-form, multistep-form e file-upload-card. Per sfogliare per categoria parti da 111.985 componenti.

La limitazione

MSW simula la rete, non il browser: non verifica CORS, cookie di terze parti né il comportamento di un proxy. E un handler troppo permissivo nasconde proprio il caso che rompe la pagina.

Dove continuare

Il quadro dei test è in Testing Library: cinque test; il data fetching senza librerie è in data fetching senza librerie; il confronto fra Server Actions e API è in Server Actions vs API.

Domande frequenti

MSW sostituisce il server nei test end-to-end?

No. Nei test di componente e di integrazione sì; per il browser vero serve un server di test o i route di Playwright.

Funziona con axios e con fetch?

Sì. Intercetta la richiesta HTTP, quindi la libreria usata non conta.

Come simulo un errore di rete?

Con HttpResponse.error() nell'handler: il client riceve un errore di rete, non una risposta.

Gli handler vanno nel codice di produzione?

No. Stanno in una cartella di test o in src/mocks, esclusa dal bundle.

Posso usare MSW nel browser durante lo sviluppo?

Sì, con il service worker avviato dal file generato: gli handler restano gli stessi dei test.