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
fight
de 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
Arena
qui retourne toujourstrue
lorsque la méthodeisOpen
est appelée. - Nous utilisons ensuite ce mock pour tester la méthode
fight
deFighter
.
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
isOpen
de l'objetArena
mocké 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
Arena
qui retournefalse
lorsque la méthodeisOpen
est appelée. -
Ensuite, nous utiliserons ce mock pour tester que la méthode
rest
deFighter
retourne "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 publiqueisOpen
qui retournetrue
par 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
Arena
en paramètre et l'assigne à l'attribut$arena
. - Définissez une méthode publique
rest
qui 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
FighterTest
qui étendPHPUnit\Framework\TestCase
. - Définissez une méthode
public function testRest()
. - Dans cette méthode, créez un mock de la classe
Arena
qui retournefalse
lorsque la méthodeisOpen
est appelée. - Utilisez ce mock pour tester que la méthode
rest
deFighter
retourne "Le combattant se repose.".
Étape 4 : Exécution du test
- Ouvrez votre terminal, naviguez jusqu'au dossier contenant votre fichier
FighterTest.php
et exécutez le fichier avec la commandephpunit FighterTest.php
. Vous devriez voir que le test passe, ce qui signifie que la méthoderest
deFighter
se comporte comme prévu lorsque l'arène est fermée.
Une solution
Vous devez être connecté pour voir le contenu.