Simuler get_option(), apply_filters() ou wp_die() sans jamais charger un cœur WordPress complet : c’est le problème que résolvent à la fois WP_Mock et Brain Monkey, avec deux philosophies différentes. Ce comparatif se limite volontairement au test unitaire pur, hors base de données ; il ne traite ni WP_UnitTestCase ni les tests d’intégration, qui répondent à un besoin distinct.
Le choix entre les deux bibliothèques se pose dès qu’un mainteneur d’extension veut tester une classe métier isolément, sans que le moindre appel à une fonction du cœur ne déclenche une erreur fatale « fonction non définie ». Les deux résolvent ce problème, mais pas avec le même vocabulaire ni les mêmes limites.
WP_Mock : un enregistrement explicite des attentes
WP_Mock fonctionne par déclaration préalable : avant d’exécuter le code testé, on enregistre chaque fonction WordPress que ce code est censé appeler, avec ses arguments et sa valeur de retour attendus.
class Test_Notifieur extends \WP_Mock\Tools\TestCase {
public function test_envoie_notification_si_option_activee() {
WP_Mock::userFunction( 'get_option', [
'args' => [ 'notifieur_actif', false ],
'return' => true,
] );
WP_Mock::userFunction( 'wp_mail', [
'times' => 1,
] );
$notifieur = new Notifieur();
$notifieur->alerter( 'stock_bas' );
}
}
Cette approche a un mérite : elle rend visible, dans le test lui-même, la liste exacte des fonctions WordPress dont dépend la classe testée. Un simple survol du test suffit à comprendre les points de contact avec le cœur.
Brain Monkey : simuler par-dessus Mockery et Patchwork
Brain Monkey adopte une approche différente : il expose des fonctions helpers qui s’appuient sur Mockery pour les vérifications et sur Patchwork pour intercepter les appels de fonctions natives PHP, y compris celles définies ailleurs dans le même espace de noms global.
use Brain\Monkey\Functions;
class Test_Notifieur extends \PHPUnit\Framework\TestCase {
protected function setUp(): void {
parent::setUp();
Brain\Monkey\setUp();
}
protected function tearDown(): void {
Brain\Monkey\tearDown();
parent::tearDown();
}
public function test_envoie_notification_si_option_activee() {
Functions\expect( 'get_option' )
->once()
->with( 'notifieur_actif', false )
->andReturn( true );
Functions\expect( 'wp_mail' )->once();
( new Notifieur() )->alerter( 'stock_bas' );
}
}

La syntaxe fluide de Mockery (expect()->once()->with()->andReturn()) rend les tests lisibles pour qui connaît déjà cette bibliothèque, largement utilisée en dehors de l’écosystème WordPress. C’est un avantage réel pour une équipe qui teste aussi du code Laravel ou Symfony en parallèle.
Tableau comparatif
| Critère | WP_Mock | Brain Monkey |
|---|---|---|
| Dépendances | PHPUnit seul | Mockery et Patchwork |
| Syntaxe | Tableau d’arguments | Chaînage fluide façon Mockery |
| Simulation des hooks | Helpers dédiés expectAction, expectApplied | Namespace Brain\Monkey\Actions et Filters |
| Fonctions non déclarées | Doit stubber chaque fonction appelée | Idem, via Patchwork pour l’interception |
| Courbe d’apprentissage | Plus directe si Mockery est inconnu | Plus rapide si Mockery est déjà maîtrisé |
Les hooks, terrain où les deux bibliothèques se ressemblent le plus
Pour vérifier qu’un filtre est bien appliqué, les deux bibliothèques proposent une syntaxe dédiée plutôt qu’un simple mock de fonction :
- WP_Mock :
WP_Mock::expectFilterAdded( 'the_content', [ $this->instance, 'filtrer' ] ); - Brain Monkey :
Filters\expectApplied( 'the_content' )->once()->with( 'texte brut' );
Dans les deux cas, la limite est la même : ces bibliothèques ne rejouent pas le comportement réel du filtre WordPress, elles vérifient seulement qu’il a été enregistré ou appelé avec les bons arguments. Un test qui passe ne garantit donc pas que la fonction de rappel produit le bon résultat une fois exécutée dans un vrai WordPress ; il garantit que la classe interagit correctement avec l’API attendue.
Notre verdict
Pour une équipe qui démarre un projet neuf sans historique de tests, Brain Monkey a l’avantage d’une syntaxe plus proche des standards actuels de simulation en PHP, et sa dépendance à Patchwork ouvre la possibilité de stubber des fonctions non liées à WordPress. WP_Mock garde un intérêt réel pour une extension déjà construite autour de ses conventions, ou pour une équipe qui préfère une déclaration d’attentes centralisée en tableau plutôt qu’un chaînage d’appels. Aucun des deux ne remplace un test d’intégration : ils servent uniquement à isoler la logique métier du reste du cœur, rapidement et sans base de données.