Mockery pour PHP : guide complet avec exemples
1. Qu'est-ce que Mockery et pourquoi l'utiliser ?
Mockery est une bibliothèque PHP puissante et flexible pour créer des objets mock (mock objects). Conçue pour les tests unitaires (unit testing), elle permet aux développeurs d'isoler le code testé de ses dépendances. Au lieu d'utiliser des objets réels (comme une connexion à une base de données, des clients API ou le système de fichiers), vous créez des "bouchons" (mocks) qui imitent le comportement des originaux. Cela rend les tests rapides, fiables et indépendants des facteurs externes.
Pourquoi en avez-vous besoin ? Imaginez que vous testez une classe OrderProcessor qui envoie un e-mail après une commande. Si vous utilisez un Mailer réel, votre test sera lent, dépendra de la disponibilité du serveur SMTP et pourrait même envoyer des e-mails à de vrais utilisateurs. Avec Mockery, vous créez un Mailer "factice" qui vérifie simplement si la méthode send() a été appelée avec les bons arguments. Cela vous permet de vous concentrer sur la logique de OrderProcessor, et non sur l'infrastructure.
Mockery ne se limite pas à remplacer des objets. Elle offre une API riche pour décrire des attentes (expectations) : vous pouvez spécifier combien de fois une méthode doit être appelée, avec quels arguments, dans quel ordre, et ce qu'elle doit retourner. Cela rend les tests non seulement isolés, mais aussi auto-documentés, car les attentes décrivent explicitement les interactions entre les objets.
2. Installation
Mockery s'installe via Composer, le gestionnaire de paquets standard pour PHP. Il est recommandé de l'installer comme dépendance de développement (require-dev), car elle n'est pas nécessaire en production.
composer require --dev mockery/mockery
Après l'installation, vérifiez que votre fichier composer.json contient l'entrée suivante dans la section require-dev :
{
"require-dev": {
"mockery/mockery": "^1.6"
}
}
Si vous utilisez PHPUnit, Mockery s'intègre nativement via le trait \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration.
3. Démarrage rapide
Créons un test simple qui illustre les fonctionnalités de base de Mockery. Supposons que nous ayons une classe Calculator qui dépend d'un service Logger.
<?php
// Classes d'exemple
interface Logger {
public function log(string $message): void;
}
class Calculator {
private Logger $logger;
public function __construct(Logger $logger) {
$this->logger = $logger;
}
public function add(int $a, int $b): int {
$result = $a + $b;
$this->logger->log("Addition de $a et $b, résultat : $result");
return $result;
}
}
// Test avec Mockery
use PHPUnit\Framework\TestCase;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
class CalculatorTest extends TestCase {
use MockeryPHPUnitIntegration;
public function testAddLogsCorrectly(): void {
// 1. Créer un mock pour Logger
$loggerMock = Mockery::mock(Logger::class);
// 2. Définir l'attente : la méthode log() doit être appelée 1 fois
// avec un message spécifique
$loggerMock->shouldReceive('log')
->once()
->with('Addition de 2 et 3, résultat : 5');
// 3. Créer l'objet testé avec le mock
$calculator = new Calculator($loggerMock);
// 4.