# Tester l’envoi vers Mailjet sans dépendre de son API en CI

> Intercepter les appels HTTP sortants vers Mailjet pour garder une suite de tests rapide, déterministe et exécutable même sans connexion réseau en intégration continue.

- Auteur : WordPress Développement
- Publié le : 2021-05-16
- Mis à jour le : 2021-05-16
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/mocker-appels-http-mailjet-ci/

## L’essentiel

- Interception via le filtre pre_http_request
- Fixtures de réponses réalistes
- SendGrid non traité, testé à part

73 requêtes HTTP sortantes en une seule exécution de suite de tests : c'est le chiffre qu'on a mesuré un jour sur un projet qui envoyait un e-mail transactionnel via Mailjet à chaque test touchant à la newsletter, sans aucune interception. Le pipeline mettait alors près de trois minutes à boucler, pour un résultat instable dès que l'API répondait un peu lentement.

La solution ne consiste pas à supprimer ces tests, précieux pour vérifier que le bon contenu part bien vers le bon destinataire, mais à intercepter les appels HTTP avant qu'ils ne quittent le serveur de CI. Ce billet ne traite pas de SendGrid, dont l'intégration diffère suffisamment pour mériter son propre article.

## Le point d'interception : le filtre pre_http_request

WordPress fournit un filtre central pour toute requête HTTP sortante, quel que soit le service appelé : `pre_http_request`. En y accrochant une fonction qui retourne directement une réponse simulée, on court-circuite `wp_remote_post` avant même qu'il ne tente une connexion réseau.

```
add_filter( 'pre_http_request', function ( $preempt, $args, $url ) {
    if ( false === strpos( $url, 'api.mailjet.com' ) ) {
        return $preempt;
    }

    return array(
        'headers'  => array(),
        'body'     => wp_json_encode( array( 'Messages' => array( array( 'Status' => 'success' ) ) ) ),
        'response' => array( 'code' => 200, 'message' => 'OK' ),
    );
}, 10, 3 );
```

Ce filtre ne doit s'activer que dans le contexte des tests, jamais en production : on l'ajoute typiquement dans le bootstrap de la suite, ou dans une classe utilitaire dédiée aux tests d'extension marketing.

## Construire des fixtures de réponses réalistes

Une réponse simulée trop simpliste masque des bugs réels. Il vaut mieux capturer, une fois, une vraie réponse de l'API Mailjet en environnement de test personnel, puis la rejouer telle quelle dans les fixtures, en anonymisant les adresses e-mail qu'elle contient.

> L'essentiel à retenir : Interception via le filtre pre_http_request ; Fixtures de réponses réalistes ; SendGrid non traité, testé à part

- Réponse de succès complète, avec l'identifiant de message Mailjet
- Réponse d'erreur 400 pour une adresse e-mail invalide
- Réponse d'erreur 401 pour une clé API expirée ou révoquée

## Écrire le test du connecteur d'envoi

Le test vérifie que le connecteur construit correctement le corps de la requête envoyée à Mailjet, avec le bon destinataire et le bon modèle d'e-mail, sans jamais interroger le vrai service.

```
class Test_Connecteur_Mailjet extends WP_UnitTestCase {

    public function test_envoi_construit_le_bon_destinataire() {
        $requete_capturee = null;

        add_filter( 'pre_http_request', function ( $preempt, $args ) use ( &$requete_capturee ) {
            $requete_capturee = $args;
            return array( 'response' => array( 'code' => 200 ), 'body' => '{}' );
        }, 10, 2 );

        Connecteur_Mailjet::envoyer( 'contact@exemple.fr', 'bienvenue' );

        $this->assertStringContainsString( 'contact@exemple.fr', $requete_capturee['body'] );
    }
}
```

### Vérifier la gestion des erreurs, pas seulement le succès

Un connecteur qui ne gère que le cas heureux se retrouve démuni le jour où Mailjet répond réellement en erreur. Le test doit donc aussi simuler une réponse 400 et vérifier que le connecteur journalise l'échec plutôt que de planter silencieusement.

## Éviter les faux positifs liés au filtre global

Un piège fréquent : oublier de retirer le filtre `pre_http_request` après le test, ce qui contamine les tests suivants si ceux-ci appellent un autre service HTTP. La méthode `tearDown()` de PHPUnit doit systématiquement retirer les filtres ajoutés en amont.

1. Ajouter le filtre dans `setUp()` ou directement dans le test
2. Capturer les arguments de la requête dans une variable locale
3. Retirer le filtre dans `tearDown()`, même en cas d'échec du test

> Sur nos projets, la règle qui a le mieux tenu : aucun test ne doit dépendre de la disponibilité d'un service tiers pour passer au vert un vendredi soir.

## En résumé

Intercepter les appels sortants vers Mailjet via `pre_http_request` transforme une suite de tests lente et dépendante du réseau en une suite rapide et parfaitement déterministe. Les fixtures de réponses réalistes, capturées une fois puis anonymisées, garantissent que le connecteur reste testé fidèlement, y compris sur ses cas d'erreur.
