PHPUnit comment mocker / simuler un objet et des méthodes
Lorsque l’on commence à utiliser PHPunit, il arrive fréquement que l’on se retrouve face au besoin de simuler une méthode ou un objet. Heureusement PHPunit a quelques méthodes qui peuvent être très utile.
Comment simuler un objet
La manière la plus simple de créer un objet mocké
$product = $this->getMockBuilder('\Product')
->getMock();
ou
$product = $this->getMockBuilder('\Product')
->setMethods(array())
->getMock();
Ce produit est un objet mocké dont les méthodes
- sont toutes présentes
- retournent toujours null par default
- sont facilement remplaçable
Si par contre on passe null dans le setMethods
$product = $this->getMockBuilder('\Product')
->setMethods(null)
->getMock();
Ce produit est un objet mocké dont les méthodes
- retourne la véritable valeur
- ne sont pas remplaçable
Si l’on passe un array contenant des noms de méthode
$product = $this->getMockBuilder('\Product')
->setMethods(array('getName','foobar')
->getMock();
Les méthodes citées
- retournent toujours null par default
- sont facilement remplaçable
quant aux autres
- retourne la véritable valeur
- ne sont pas remplaçable
En gros cela signifie que toutes les méthodes de l’objet Product retourneront les valeurs définies sauf getName et foobar qui elles retourneront null.
Si l’on se retrouve face à un constructeur qui empêche de le construire sans connaitre quelques valeurs, il est possible d’utilise l’option disableOriginalConstructor()
$product = $this->getMockBuilder('\Product')
->disableOriginalConstructor()
->setMethods(array('getName','foobar')
->getMock();
Comment simuler une méthode
Une fois l’objet mocké, il est aussi possible de remplacer la valeur de retour d’une méthode. Pour ce faire, il suffit d’utiliser la méthode ->excepts
$product = $this->getMockBuilder('\Product')
->setMethods(array('getName','foobar')
->getMock();
$product->expects($this->once())
->method('getName')
->will($this->returnValue('myName');
$product->expects($this->any())
->method('foobar')
->will($this->returnValue('foo!');
Dans cette exemple, la méthode getName retounera toute le temps le string « myName », mais le test sera un echec si elle est appelé plus d’une fois, alors que l’appel de la méthode foobar est illimité et retourne le string « foo! ».