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.

- 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.
- Ajouter le filtre dans
setUp()ou directement dans le test - Capturer les arguments de la requête dans une variable locale
- 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.