Tester les règles métier isolément
Objectif : Écrire des tests unitaires qui vérifient les invariants d’un contact sans accéder à une base réelle.
Un contact mal formé ne doit pas atteindre le stockage. Pour vérifier cette règle sans démarrer votre application ni vous connecter à une base réelle, vous allez tester directement le service métier et ses réponses aux données invalides.
Les couches et leurs responsabilités ont été présentées dans « Définir les responsabilités des couches » ; ici, vous concentrez le test sur ContactService. Un test unitaire appelle une unité de code isolée et vérifie son résultat avec des assertions PHPUnit : il ne cherche pas à valider toute une requête HTTP ni le fonctionnement d’une base.
Préparer le test
Le fichier prévu à cet effet est tests/Unitaire/ContactServiceTest.php. L’exemple ci-dessous suppose les signatures du service déjà établi : son constructeur reçoit un dépôt, et ajouter() reçoit le nom, le courriel et le téléphone. Il vérifie que les données qui enfreignent les règles métier sont rejetées par une InvalidArgumentException.
<?php
declare(strict_types=1);
namespace Tests\Unitaire;
use App\Depot\ContactDepot;
use App\Service\ContactService;
use InvalidArgumentException;
use PDO;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
final class ContactServiceTest extends TestCase
{
private ContactService $service;
protected function setUp(): void
{
$pdo = new PDO('sqlite::memory:');
$depot = new ContactDepot($pdo);
$this->service = new ContactService($depot);
}
#[DataProvider('contactsInvalides')]
public function testRefuseUnContactInvalide(
string $nom,
string $courriel,
string $telephone
): void {
$this->expectException(InvalidArgumentException::class);
$this->service->ajouter($nom, $courriel, $telephone);
}
public static function contactsInvalides(): iterable
{
yield 'nom vide' => ['', '[email protected]', '0600000000'];
yield 'courriel mal formé' => ['Léa Martin', 'pas-un-courriel', '0600000000'];
}
}La connexion SQLite en mémoire permet de construire le dépôt sans contacter une base de développement ou de production. Le test ne crée pas de table : les cas fournis doivent être refusés avant tout appel de persistance. Le fait d’instancier le dépôt n’est pas le sujet du test ; vous vérifiez ici que les entrées invalides échouent au niveau métier.
Comprendre les assertions et les cas
expectException() est une assertion PHPUnit qui fait réussir le test si l’appel suivant lève le type d’exception attendu. Si le service accepte le contact, ou si une autre erreur survient, le test échoue. Chaque ligne produite par contactsInvalides() fournit un cas différent à la même méthode de test : vous vérifiez ainsi séparément le nom vide et le courriel mal formé.
Le jeu de données exprime les règles à l’aide d’exemples concrets. Ajoutez-y un cas uniquement lorsqu’il couvre une règle définie par votre service, par exemple une valeur obligatoire manquante. Évitez de tester des détails d’implémentation comme le nom d’une variable interne : un test utile protège un comportement attendu, pas la manière dont il est codé.
Exécuter et interpréter le résultat
vendor/bin/phpunit tests/Unitaire/ContactServiceTest.phpPHPUnit 11.x
.. 2 / 2 (100%)
OK (2 tests, 2 assertions)Les deux points représentent les deux cas fournis par le jeu de données. Si SQLite n’est pas disponible dans votre environnement PHP, activez son extension ou adaptez la préparation du dépôt à l’environnement local ; cette leçon n’exige pas de base réelle. Vous pouvez aussi lancer la suite complète avec vendor/bin/phpunit depuis la racine, comme configuré dans la leçon précédente.
Un test qui échoue signale un écart entre la règle attendue et le comportement observé. Vérifiez d’abord que les données du cas correspondent aux règles de ContactService, puis que le service lève bien le type d’exception prévu. N’assouplissez pas une validation métier uniquement pour obtenir une suite verte : corrigez le comportement ou l’attente selon la règle voulue.
À retenir
- Testez ContactService directement pour vérifier ses règles métier.
- Utilisez les assertions PHPUnit pour rendre explicite le comportement attendu.
- Centralisez plusieurs entrées similaires dans un jeu de données.
- Gardez le test indépendant d’une base réelle et vérifiez les signatures de votre service.
Dans la prochaine leçon, vous remplacerez les dépendances du service par des doublures afin de vérifier précisément ses échanges avec le dépôt.