# Mock Service Worker intercepte les appels API dans vos tests JS de blocs

> Présentation de MSW pour intercepter les requêtes réseau au niveau des tests de composants React, plutôt que de mocker fetch à la main dans chaque fichier.

- Auteur : WordPress Développement
- Publié le : 2023-11-14
- Mis à jour le : 2026-09-30
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/mock-service-worker-intercepte-appels-api-blocs/

## L’essentiel

- MSW intercepte au niveau réseau, pas au niveau de la fonction fetch
- Les handlers se réutilisent entre tests et entre projets
- Le composant testé ignore totalement qu'il est mocké

`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

> L'essentiel à retenir : MSW intercepte au niveau réseau, pas au niveau de la fonction fetch ; Les handlers se réutilisent entre tests et entre projets ; Le composant testé ignore totalement qu'il est mocké

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.
