global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve(donneesFictives) })); — cette ligne, dupliquée avec de légères variantes dans neuf fichiers de test différents, formait la base des tests d’un bloc Gutenberg d’affichage d’avis clients pour un site de vente de matériel photo d’occasion. Chaque test redéfinissait fetch globalement, avec le risque constant qu’un test oublie de le restaurer et pollue les tests suivants.
Mock Service Worker (MSW) propose une approche différente : au lieu de remplacer la fonction fetch elle-même, il intercepte les requêtes au niveau du réseau simulé, ce qui laisse le composant testé se comporter exactement comme en production, sans avoir conscience d’être mocké.
Pourquoi mocker fetch directement pose problème
Remplacer global.fetch fonctionne, mais oblige à réimplémenter à la main tout ce que fetch fait normalement : gestion des codes de statut, des en-têtes, de la sérialisation JSON, des erreurs réseau. Chaque test réinvente sa propre version simplifiée de ce comportement, avec des incohérences qui s’accumulent d’un fichier à l’autre.
Mettre en place MSW pour un bloc

MSW se configure via un fichier de handlers, qui décrit les routes interceptées et les réponses associées, indépendamment de chaque fichier de test :
// tests/mocks/handlers.js
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('/wp-json/avis-clients/v1/produits/:id/avis', ({ params }) => {
return HttpResponse.json([
{ auteur: 'M. Dubreuil', note: 5, commentaire: 'Objectif reçu comme neuf.' },
{ auteur: 'S. Amrani', note: 4, commentaire: 'Léger jeu sur la bague de zoom.' },
]);
}),
];
Un serveur de test démarre ces handlers avant la suite, et les arrête après, sans intervention dans chaque fichier :
// tests/mocks/server.js
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
// jest.setup.js
import { server } from './tests/mocks/server';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
Le test de composant devient indépendant du mécanisme de mock
test('affiche les avis clients recuperes depuis l API', async () => {
render(<BlocAvisClients produitId={42} /></blocavisclients>);
expect(await screen.findByText(/Objectif reçu comme neuf/)).toBeInTheDocument();
expect(screen.getByText('M. Dubreuil')).toBeInTheDocument();
});
Le composant appelle réellement fetch('/wp-json/avis-clients/v1/produits/42/avis') ; MSW intercepte cette requête avant qu’elle n’atteigne le réseau, et répond avec le corps défini dans le handler. Aucune ligne du composant ne connaît l’existence du mock.
Tester un cas d’erreur réseau
Un test peut redéfinir localement un handler pour simuler une panne, sans toucher au reste de la configuration :
test('affiche un message si les avis ne peuvent pas être chargés', async () => {
server.use(
http.get('/wp-json/avis-clients/v1/produits/:id/avis', () => {
return new HttpResponse(null, { status: 500 });
})
);
render(<BlocAvisClients produitId={42} /></blocavisclients>);
expect(await screen.findByText(/impossible de charger les avis/i)).toBeInTheDocument();
});
Ce que MSW ne couvre pas ici
- Les mocks côté serveur PHP (appels HTTP sortants depuis WordPress) relèvent d’un outillage distinct, propre à PHPUnit, sans lien avec MSW.
- MSW ne teste pas la validité du contrat d’API réel : les handlers doivent être tenus à jour manuellement si le format de réponse de l’endpoint évolue.
- Un excès de handlers génériques réutilisés partout peut masquer des variations légitimes entre blocs ; chaque handler mérite d’être relu périodiquement.
Un mock qui intercepte au niveau réseau laisse le composant se comporter honnêtement ; un mock qui remplace la fonction appelante triche un peu plus à chaque test.
En résumé
MSW remplace neuf implémentations disparates de mock manuel par un jeu de handlers unique, partagé entre tous les tests du bloc, et réutilisable sur d’autres projets front du même type. Le gain principal n’est pas seulement la réduction du code de test, mais la garantie que chaque composant est testé dans les mêmes conditions réseau qu’en production.