# Antipatterns des tests d’un connecteur CRM : intégrations HubSpot mal testées

> Vérifier la requête envoyée à HubSpot ne dit rien de ce qui se passe si l'API répond une erreur. Un tour d'horizon des antipatterns les plus courants.

- Auteur : WordPress Développement
- Publié le : 2022-06-19
- Mis à jour le : 2022-06-19
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/antipatterns-tests-connecteur-crm-hubspot/

## L’essentiel

- Vérifier uniquement la requête sortante laisse la gestion d'erreur totalement non testée
- Un mock qui retourne toujours un succès masque les vrais bugs de production
- Le rejeu après échec doit être testé, pas seulement supposé fonctionner

Une suite de tests peut afficher 100 % de réussite et ne rien garantir sur le comportement réel en production, dès qu'elle se limite à vérifier que la bonne requête HTTP est partie vers HubSpot, sans jamais se demander ce qui arrive quand la réponse n'est pas celle attendue. C'est le constat récurrent après l'audit de plusieurs connecteurs CRM développés par des équipes différentes pour des clients variés.

Ce tour d'horizon ne traite pas de Salesforce, dont l'écosystème de tests obéit à des contraintes propres à sa plateforme ; il se concentre sur les antipatterns observés spécifiquement sur des intégrations HubSpot construites en PHP, souvent bâties à partir de `wp_remote_post` ou du SDK officiel.

## Antipattern n° 1 : tester la requête, jamais la réponse d'erreur

Le cas le plus fréquent : un test qui vérifie que `wp_remote_post` a bien été appelé avec la bonne URL et le bon corps JSON, puis s'arrête là. Aucune assertion sur ce qui se produit si HubSpot répond un code 429 (limite de requêtes atteinte) ou 401 (jeton expiré).

```
// Ce que l'on voit trop souvent
public function test_synchronise_le_contact(): void
{
    $requete_capturee = null;
    add_filter('pre_http_request', function ($preempt, $args) use (&$requete_capturee) {
        $requete_capturee = $args;
        return ['response' => ['code' => 200], 'body' => '{}'];
    }, 10, 2);

    (new HubspotConnecteur())->synchroniser(['email' => 'test@example.test']);

    $this->assertNotNull($requete_capturee);
    // Fin du test : aucune vérification du comportement en cas d'échec.
}
```

Pourquoi c'est un problème : ce test prouve seulement que le code sait construire une requête, pas qu'il sait réagir à une panne. Or c'est précisément dans la réaction à la panne que se cachent la majorité des tickets support liés à un connecteur CRM.

## Antipattern n° 2 : un mock qui retourne toujours un succès

> L'essentiel à retenir : Vérifier uniquement la requête sortante laisse la gestion d'erreur totalement non testée ; Un mock qui retourne toujours un succès masque les vrais bugs de production ; Le rejeu après échec doit être testé, pas seulement supposé fonctionner

Deuxième piège fréquent : un double de test générique, réutilisé partout dans la suite, qui simule systématiquement une réponse HubSpot à 200. Pratique pour faire passer les tests rapidement, dangereux parce qu'il masque tout code de gestion d'erreur jamais réellement exercé.

- Le code contient un bloc `catch` censé gérer les erreurs HubSpot, mais aucun test ne déclenche jamais ce chemin.
- Un changement ultérieur dans ce bloc `catch` peut introduire une régression silencieuse, invisible tant que la vraie panne ne survient pas en production.
- Quoi faire : dupliquer explicitement le double de test en une version « succès » et une version « échec », utilisées consciemment selon le scénario testé.

## Antipattern n° 3 : supposer que le rejeu fonctionne, sans le tester

Un connecteur bien conçu met en file d'attente les contacts non synchronisés après une panne, pour les rejouer plus tard. Le problème observé plusieurs fois : la file d'attente existe, le code de rejeu existe, mais aucun test ne vérifie qu'un contact mis en file une première fois n'est pas dupliqué au second passage.

```
// Test manquant dans plusieurs connecteurs audités
public function test_le_rejeu_ne_duplique_pas_un_contact_deja_en_file(): void
{
    update_option('hubspot_file_attente', [
        ['email' => 'deja-en-file@example.test'],
    ]);

    $connecteur = new HubspotConnecteur();
    $connecteur->mettre_en_file(['email' => 'deja-en-file@example.test']);

    $this->assertCount(1, get_option('hubspot_file_attente'));
}
```

### Ce qu'il faut faire à la place

1. Écrire systématiquement un test « chemin heureux » et au moins un test « chemin d'erreur » pour chaque appel HubSpot, jamais l'un sans l'autre.
2. Créer des doubles de test distincts et explicitement nommés selon le scénario simulé, plutôt qu'un double générique réutilisé aveuglément.
3. Tester la file d'attente et le rejeu comme une fonctionnalité à part entière, avec ses propres cas limites de duplication.

> Un connecteur CRM qui n'a jamais vu son propre code de gestion d'erreur s'exécuter en test n'a, de fait, jamais été testé sur la partie qui compte le plus en production.

## En résumé

Ces trois antipatterns partagent une même racine : une suite de tests construite pour prouver que le code fonctionne quand tout va bien, sans jamais s'attarder sur ce qui se passe quand HubSpot ne coopère pas. Corriger ces suites ne demande pas de réécrire le connecteur, seulement d'ajouter les tests d'échec et de rejeu qui, aujourd'hui, n'existent tout simplement pas.
