Les mocks
Partie théorique
Qu'est-ce qu'un mock ?
Dans le domaine du développement logiciel, un mock est une simulation d'un objet réel utilisée pour tester le comportement de certains composants du logiciel.
Les mocks sont particulièrement utiles dans les tests unitaires, où ils peuvent être utilisés pour simuler le comportement d'objets dépendants afin de tester le comportement de l'objet cible dans des conditions contrôlées.
Les mocks sont généralement utilisés lorsque l'objet réel est imprévisible ou difficile à reproduire dans un environnement de test (par exemple, une base de données ou un service Web).
PHPUnit fournit un moyen facile de créer des mocks d'objets en PHP.
Exemple pratique
Supposons que nous avons une classe Fighter qui dépend d'une autre classe Arena.
Nous voulons tester la méthode
fightde la classeFighter, mais sans avoir à créer une véritable instance deArena.
class Fighter {
private $arena;
public function __construct(Arena $arena) {
$this->arena = $arena;
}
public function fight() {
if ($this->arena->isOpen()) {
return "Le combat commence !";
} else {
return "L'arène est fermée.";
}
}
}
Nous pouvons créer un mock de Arena pour tester la méthode fight de Fighter :
public function testFight() {
// Création d'un mock pour la classe Arena
$arena = $this->createMock(Arena::class);
// Configuration du mock pour retourner true lorsque la méthode isOpen est appelée
$arena->method('isOpen')
->willReturn(true);
$fighter = new Fighter($arena);
$this->assertEquals("Le combat commence !", $fighter->fight());
}
Dans cet exemple :
- Nous créons un mock de
Arenaqui retourne toujourstruelorsque la méthodeisOpenest appelée. - Nous utilisons ensuite ce mock pour tester la méthode
fightdeFighter.
Pourquoi la classe Arena n'est pas implémentée ?
Lorsque vous créez un mock d'un objet (ici un objet Arena), vous n'avez pas besoin de la véritable implémentation de cet objet.
En fait, c'est l'un des principaux avantages de l'utilisation des mocks : vous pouvez tester le comportement d'un objet (ici un objet
Fighter) indépendamment de ses dépendances (ici un objetArena).
Lorsque vous créez un mock de l'objet Arena avec la ligne $arena = $this->createMock(Arena::class);,
vous créez un faux objet Arena qui se comporte exactement comme vous le définissez dans votre test.
Dans cet exemple, vous définissez que la méthode
isOpende l'objetArenamocké retourne toujourstrue.
Cela vous permet de contrôler précisément le comportement de l'objet Arena dans le cadre de votre test,
sans avoir à vous soucier de la véritable implémentation de la classe Arena.
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Dans ce TP, nous allons tester la méthode rest de la classe Fighter.
Cette méthode doit retourner "Le combattant se repose." si l'arène est fermée, sinon elle doit retourner "Le combat continue, pas le temps de se reposer !".
-
Pour cela, nous allons créer un mock de la classe
Arenaqui retournefalselorsque la méthodeisOpenest appelée. -
Ensuite, nous utiliserons ce mock pour tester que la méthode
restdeFighterretourne "Le combattant se repose." lorsque l'arène est fermée.
Voici les étapes à suivre :
Étape 1 : Création d'une classe Arena minimale qui contient la méthode isOpen.
Voici comment vous pouvez le faire :
- Créez un nouveau fichier PHP nommé
Arena.php. - Dans ce fichier, déclarez une nouvelle classe appelée
Arena. - Dans la classe
Arena, définissez une méthode publiqueisOpenqui retournetruepar défaut.
Votre fichier Arena.php devrait ressembler à ceci :
class Arena {
public function isOpen() {
return true;
}
}
Maintenant, vous pouvez inclure la classe Arena dans vos fichiers Fighter.php et FighterTest.php en utilisant l'instruction require_once :
Étape 2 : Création de la classe Fighter
- Ouvrez votre éditeur de texte et créez un nouveau fichier PHP que vous nommerez
Fighter.php. - Dans ce fichier, déclarez une nouvelle classe appelée
Fighter. - Dans la classe
Fighter, définissez un attribut privé$arena. - Définissez un constructeur qui prend un objet
Arenaen paramètre et l'assigne à l'attribut$arena. - Définissez une méthode publique
restqui retourne "Le combattant se repose." si l'arène est fermée, sinon elle retourne "Le combat continue, pas le temps de se reposer !".
Votre fichier Fighter.php devrait ressembler à ceci :
require_once 'Arena.php';
class Fighter {
private $arena;
public function __construct(Arena $arena) {
$this->arena = $arena;
}
public function rest() {
if (!$this->arena->isOpen()) {
return "Le combattant se repose.";
} else {
return "Le combat continue, pas le temps de se reposer !";
}
}
}
Étape 3 : Création du test unitaire
- Créez un nouveau fichier PHP que vous nommerez
FighterTest.php. - Dans ce fichier, déclarez une nouvelle classe appelée
FighterTestqui étendPHPUnit\Framework\TestCase. - Définissez une méthode
public function testRest(). - Dans cette méthode, créez un mock de la classe
Arenaqui retournefalselorsque la méthodeisOpenest appelée. - Utilisez ce mock pour tester que la méthode
restdeFighterretourne "Le combattant se repose.".
Étape 4 : Exécution du test
- Ouvrez votre terminal, naviguez jusqu'au dossier contenant votre fichier
FighterTest.phpet exécutez le fichier avec la commandephpunit FighterTest.php. Vous devriez voir que le test passe, ce qui signifie que la méthoderestdeFighterse comporte comme prévu lorsque l'arène est fermée.
Une solution
Vous devez être connecté pour voir le contenu.