# pre_http_request intercepte une requête pour un mock d’API fiable

> Chaque appel réseau réel dans un test le rend lent, fragile et dépendant d'un service tiers. Un filtre du cœur de WordPress permet de l'intercepter avant son envoi.

- Auteur : WordPress Développement
- Publié le : 2022-05-23
- Mis à jour le : 2022-05-23
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/pre-http-request-intercepte-requete-mock-api/

## L’essentiel

- Intercepte la requête avant qu'elle ne quitte le serveur
- Retourne une réponse simulée au format attendu par l'API HTTP
- Fonctionne quelle que soit la fonction d'appel utilisée

Toute fonction de l'API HTTP de WordPress, que ce soit `wp_remote_get`, `wp_remote_post` ou `wp_remote_request`, passe par un point de passage commun avant d'envoyer réellement une requête vers un serveur distant. Ce point de passage est un filtre nommé `pre_http_request`, et il permet d'intercepter n'importe quel appel réseau avant son envoi, pour lui substituer une réponse entièrement simulée.

Pour des développeurs qui veulent des tests reproductibles, exécutables sans connexion internet et sans dépendre de la disponibilité réelle d'un service tiers, ce filtre constitue la solution la plus directe offerte par le cœur de WordPress lui-même, sans nécessiter de bibliothèque tierce supplémentaire.

## Comprendre où se situe ce filtre

Toutes les fonctions de haut niveau de l'API HTTP finissent par appeler la classe `WP_Http`, dont la méthode `request` applique le filtre `pre_http_request` avant toute tentative d'envoi réel. Si une fonction accrochée à ce filtre retourne autre chose que `false`, sa valeur de retour est utilisée telle quelle comme réponse, et aucune connexion réseau n'est jamais établie.

```
add_filter( 'pre_http_request', function ( $reponse_court_circuitee, $arguments, $url ) {
    if ( str_contains( $url, 'api.service-externe.test' ) ) {
        return [
            'headers'  => [],
            'body'     => wp_json_encode( [ 'statut' => 'ok' ] ),
            'response' => [ 'code' => 200, 'message' => 'OK' ],
            'cookies'  => [],
        ];
    }
    return $reponse_court_circuitee;
}, 10, 3 );
```

Le tableau retourné doit respecter précisément la structure attendue par l'API HTTP de WordPress : les clés `headers`, `body`, `response` et `cookies` sont toutes nécessaires pour que les fonctions comme `wp_remote_retrieve_body` ou `wp_remote_retrieve_response_code` fonctionnent correctement sur cette réponse simulée, exactement comme elles le feraient sur une vraie réponse réseau.

## Étape par étape : mettre en place le mock dans un test

> L'essentiel à retenir : Intercepte la requête avant qu'elle ne quitte le serveur ; Retourne une réponse simulée au format attendu par l'API HTTP ; Fonctionne quelle que soit la fonction d'appel utilisée

```
class SynchronisationServiceTest extends WP_UnitTestCase {

    public function test_synchronisation_reussie(): void {
        add_filter( 'pre_http_request', [ $this, 'simule_reponse_service' ], 10, 3 );

        $resultat = ( new SynchronisationService() )->synchroniser();

        $this->assertTrue( $resultat );

        remove_filter( 'pre_http_request', [ $this, 'simule_reponse_service' ], 10 );
    }

    public function simule_reponse_service( $reponse, $arguments, $url ) {
        return [
            'headers'  => [],
            'body'     => wp_json_encode( [ 'synchronise' => true ] ),
            'response' => [ 'code' => 200, 'message' => 'OK' ],
            'cookies'  => [],
        ];
    }
}
```

Retirer le filtre explicitement après le test, avec `remove_filter`, évite qu'il ne persiste et n'affecte un autre test qui, lui, aurait besoin d'un comportement réseau différent, voire d'un comportement d'échec volontaire.

## Simuler un échec réseau ou une erreur HTTP

```
public function test_synchronisation_echoue_si_service_indisponible(): void {
    add_filter( 'pre_http_request', function () {
        return new WP_Error( 'http_request_failed', 'Impossible de joindre le service' );
    } );

    $resultat = ( new SynchronisationService() )->synchroniser();

    $this->assertFalse( $resultat );
}
```

Retourner un objet `WP_Error` plutôt qu'un tableau de réponse simule fidèlement une panne réseau réelle, ce qui permet de vérifier que le code appelant gère correctement ce cas sans jamais dépendre d'une véritable coupure de connexion pour tester ce scénario.

## Cibler précisément l'URL concernée

Un filtre `pre_http_request` mal ciblé intercepte toutes les requêtes HTTP du site, y compris celles totalement sans rapport avec le service testé. Vérifier systématiquement l'URL, ou un fragment distinctif de celle-ci, avant de retourner une réponse simulée, évite de fausser accidentellement d'autres appels réseau que le test n'a pas l'intention de mocker :

- Vérifier l'hôte de l'URL avec `wp_parse_url` plutôt qu'une simple recherche de sous-chaîne fragile.
- Retourner la valeur reçue en premier argument, inchangée, quand l'URL ne correspond pas au service ciblé, pour laisser les autres filtres ou le comportement réel s'appliquer.
- Documenter, dans le nom de la méthode de simulation, le service précis concerné, pour qu'un futur lecteur du test comprenne immédiatement sa portée.

> Un test qui dépend d'un vrai appel réseau n'est jamais totalement fiable : il hérite de la latence, de la disponibilité et des quotas d'un service que le test ne contrôle pas. Court-circuiter la requête à la source règle ces trois problèmes en même temps.

## Ce que ce mécanisme ne remplace pas

Court-circuiter une requête avec `pre_http_request` vérifie que le code appelant traite correctement une réponse donnée, mais ne vérifie jamais que le format réellement renvoyé par le service tiers correspond à ce qui est simulé. Un changement de format côté service externe, non répercuté dans les fixtures du test, peut passer inaperçu. Un test de contrat séparé, exécuté ponctuellement contre le vrai service, reste utile en complément pour détecter ce type de dérive.

## En résumé

Le filtre `pre_http_request`, disponible nativement dans le cœur de WordPress, offre un point d'interception fiable pour simuler n'importe quel appel réseau avant son envoi réel. Utilisé avec une réponse simulée fidèle au format attendu par l'API HTTP, il rend les tests plus rapides, reproductibles hors ligne, et totalement indépendants de la disponibilité réelle d'un service tiers.
