Existe-t-il un moyen de définir différentes fausses attentes pour différents arguments d'entrée? Par exemple, j'ai une classe de couche de base de données appelée DB. Cette classe a une méthode appelée "Query (string $ query)", cette méthode prend une chaîne de requête SQL en entrée. Puis-je créer une maquette pour cette classe (DB) et définir des valeurs de retour différentes pour différents appels de méthode de requête qui dépendent de la chaîne de requête d'entrée?
117
Réponses:
La bibliothèque PHPUnit Mocking (par défaut) détermine si une attente correspond uniquement en fonction du matcher passé au
expects
paramètre et de la contrainte transmise àmethod
. Pour cette raison, deuxexpect
appels qui ne diffèrent que par les arguments passés àwith
échoueront car les deux correspondront mais un seul vérifiera comme ayant le comportement attendu. Voir le cas de reproduction après l'exemple de travail réel.Pour votre problème, vous devez utiliser
->at()
ou->will($this->returnCallback(
comme indiqué dansanother question on the subject
.Exemple:
Reproduit:
Reproduisez pourquoi deux appels -> with () ne fonctionnent pas:
Résulte en
la source
$this->anything()
comme l'un des paramètres pour->logicalOr()
vous permettre de fournir une valeur par défaut pour d'autres arguments que celui qui vous intéresse.Ce n'est pas idéal à utiliser
at()
si vous pouvez l'éviter car, comme le prétendent leurs documentsDepuis 4.1, vous pouvez utiliser
withConsecutive
par exemple.Si vous souhaitez le faire revenir sur des appels consécutifs:
la source
Fatal error: Call to undefined method PHPUnit_Framework_MockObject_Builder_InvocationMocker::withConsecutive()
, mis à niveau vers la version 4.1 en un clin d'œil avec Composer et cela fonctionne.willReturnOnConsecutiveCalls
tué.D'après ce que j'ai trouvé, la meilleure façon de résoudre ce problème est d'utiliser la fonctionnalité de carte de valeur de PHPUnit.
Exemple tiré de la documentation de PHPUnit :
Ce test réussit. Comme vous pouvez le voir:
D'après ce que je peux dire, cette fonctionnalité a été introduite dans PHPUnit 3.6 , elle est donc suffisamment "ancienne" pour pouvoir être utilisée en toute sécurité sur à peu près n'importe quel environnement de développement ou de préparation et avec n'importe quel outil d'intégration continue.
la source
Il semble que Mockery ( https://github.com/padraic/mockery ) le supporte. Dans mon cas je veux vérifier que 2 index sont créés sur une base de données:
La dérision, fonctionne:
PHPUnit, cela échoue:
Mockery a également une plus belle syntaxe à mon humble avis. Cela semble être un peu plus lent que la capacité de simulation intégrée de PHPUnits, mais YMMV.
la source
Intro
D'accord, je vois qu'une solution est fournie pour Mockery, donc comme je n'aime pas Mockery, je vais vous donner une alternative à Prophecy mais je vous suggère d'abord de lire la différence entre Mockery et Prophecy.
En bref : "La prophétie utilise une approche appelée liaison de message - cela signifie que le comportement de la méthode ne change pas avec le temps, mais est plutôt changé par l'autre méthode."
Code problématique du monde réel à couvrir
Solution PhpUnit Prophecy
Résumé
Encore une fois, Prophecy est plus impressionnant! Mon astuce est de tirer parti de la nature de liaison de messagerie de Prophecy et même si cela ressemble malheureusement à un code d'enfer javascript de rappel typique, commençant par $ self = $ this; comme vous devez très rarement écrire des tests unitaires comme celui-ci, je pense que c'est une bonne solution et c'est vraiment facile à suivre, à déboguer, car il décrit en fait l'exécution du programme.
BTW: Il existe une deuxième alternative mais nécessite de changer le code que nous testons. Nous pourrions envelopper les fauteurs de troubles et les déplacer dans une classe distincte:
pourrait être enveloppé comme:
et c'est tout mais comme je ne voulais pas créer une autre classe pour cela, je préfère la première.
la source