Tests Unitaires : Au-delà du piège des 75 % de couverture
Maîtrisez les Mocks et les Stubs pour tester des logiques métier complexes à la vitesse de l'éclair, sans jamais toucher à la base de données Salesforce.
André Rödel
5/14/20263 min temps de lecture
Si vous travaillez dans l'écosystème Salesforce depuis un certain temps, vous connaissez bien « la danse des 75 % ». C’est ce moment, juste avant un déploiement majeur, où vous ajoutez frénétiquement des classes @isTest simplement pour atteindre un chiffre, sacrifiant souvent la qualité réelle au profit de la barrière de déploiement.
Mais voici la dure vérité : la couverture de code n'est pas synonyme de qualité de code.
La plupart des « tests unitaires » dans Salesforce sont en réalité des tests d'intégration. Ils insèrent des enregistrements, déclenchent des triggers, exécutent des requêtes SOQL et finissent par vérifier un résultat. Bien que ces tests soient nécessaires, ils sont lents, fragiles et dépendent entièrement de l'état de la base de données. Si vous voulez construire une architecture vraiment scalable, vous devez apprendre à tester votre logique en isolation complète.
Voyons comment dépasser la base de données et commencer à écrire de « vrais » tests unitaires.
1. Le problème avec la base de données
Salesforce est une plateforme centrée sur la base de données, notre premier réflexe est donc toujours d'utiliser insert et select. Cependant, s'appuyer sur le DML dans vos tests a un prix élevé :
Temps d'exécution : Insérer 200 Comptes et 400 Contacts juste pour tester une instruction if dans une classe de service prend des secondes. Multipliez cela par 1 000 tests, et votre déploiement prend des heures.
Dépendances de données : Vos tests ne devraient pas échouer parce qu'une nouvelle règle de validation ou un champ obligatoire a été ajouté à un objet qui n'est même pas pertinent pour la logique que vous testez.
La « jungle » des effets de bord : Le DML déclenche une avalanche d'automatisations (Flows, Triggers, Managed Packages) qui podem interférer avec la logique spécifique que vous essayez de valider.
2. Mocks vs. Stubs : Les armes secrètes
Pour tester en isolation, nous utilisons des « doublures de test » (Test Doubles). Dans Apex, les deux types les plus courants sont les Stubs et les Mocks.
Le Stub
Un Stub est un objet « bête » qui fournit des réponses pré-enregistrées aux appels effectués pendant le test. Si votre service doit demander à une classe Selector une liste d'Opportunités, vous n'exécutez pas de requête SOQL. Vous dites au Stub : « Chaque fois que quelqu'un demande des Opportunités, renvoie simplement ces trois enregistrements que j'ai créés en mémoire. »
Le Mock
Un Mock est plus sophistiqué. Il ne se contente pas de fournir des données, il se souvient également de la manière dont il a été appelé. Il vous permet de vérifier le comportement : « Ma classe de service a-t-elle réellement appelé la méthode 'EmailNotification' ? A-t-elle été appelée exactement une fois ? L'objet de l'e-mail était-il correct ? »
3. Rendre le code « testable » (Injection de dépendance)
Vous ne pouvez pas « mocker » ce que vous ne contrôlez pas. Si votre logique ressemble à ceci :
Vous êtes piégé. Vous devez insérer une commande (Order) en base de données pour tester cela. Pour corriger cela, vous devez « injecter » vos dépendances :
Désormais, dans votre test, vous pouvez passer un Mock Selector qui renvoie une liste d'articles sans jamais toucher à la base de données.
4. Comment l'implémenter : fflib et StubProvider
Dans l'Apex moderne, nous avons deux manières principales de gérer cela :
Le Framework fflib (Apex Enterprise Patterns) : C'est la référence absolue pour les Orgs à grande échelle. Il intègre un support natif pour Apex Mocks, ce qui rend extrêmement facile le "mocking" des Selectors, des classes Domain et des Services. Si vous envisagez cette approche, j'ai précédemment écrit une analyse critique de la scalabilité de fflib vs overhead qui peut vous aider à décider si cela convient à votre architecture.
Apex Stub API (System.StubProvider) : C'est l'approche native de Salesforce. Elle vous permet de créer un objet « Proxy » qui intercepte les appels de méthode à l'exécution. C'est plus minimaliste que fflib mais extrêmement puissant pour les architectures personnalisées.
5. Le résultat : Vitesse et Confiance
Lorsque vous passez des tests d'intégration aux « vrais » tests unitaires, le changement est transformateur :
Vitesse de la suite de tests : Les tests qui s'exécutent en mémoire sont presque instantanés. Vous pouvez exécuter des centaines de tests en quelques secondes.
Échecs isolés : Si un test échoue, vous savez exactement où se trouve le bug. Il est dans la logique, pas dans un Flow cassé ou une valeur de liste de choix modifiée.
Discipline architecturale : Écrire du code testable vous force à respecter la Séparation des préoccupations (SoC). Si votre code est difficile à tester, c'est probablement qu'il est mal conçu.
Verdict Final
L'exigence des 75 % est un plancher, pas um plafond. En maîtrisant les Mocks et les Stubs, vous arrêtez de tester « la plateforme » et vous commencez à tester « votre logique ». C’est la différence entre être un développeur qui se contente d'atteindre la couverture et un Architecte qui construit des systèmes résilients et performants.
Arrêtez d'insérer. Commencez à "mocker".
Contact
Contactez-nous pour toute suggestion ou question technique.
© 2026. Tous droits réservés.
