Disons que j'ai une classe qui contient une fonction qui utilise une indication de type comme celle-ci:
class Testable
{
function foo (Dependency $dependency)
{
}
}
Et je veux tester cette classe Testable
en utilisant ce code:
$dependencyMock = $this->getMockBuilder('Dependency')
->disableOriginalConstructor()
->getMock();
$testable = new Testable($dependencyMock);
Si j'utilise PHPUnit pour créer un stub de $ dependency et que j'essaye d'appeler la fonction foo
en utilisant ce simulacre (comme ci-dessus), j'obtiendrai une erreur fatale qui dit:
L'argument 1 passé à la fonction foo () doit être une instance de Dependency, instance de Mock_Foo donnée
Comment puis-je tester cette fonction avec PHPUnit et encore stub $dependency
?
Utilisez un espace de noms complet lorsque vous utilisez la moquerie, cela résoudra le problème d'héritage de la moquerie.
$dependencyMock = $this->getMockBuilder('\Some\Name\Space\Dependency')
->disableOriginalConstructor()
->getMock();
$testable = new Testable($dependencyMock);
Le moyen le plus simple d'utiliser un espace de noms complet dans PHP 5.4+ est avec la méthode statique de classe:
SomeClass::class
Donc, dans l'exemple du PO:
$dependencyMock = $this->getMockBuilder(Dependency::class)
->disableOriginalConstructor()
->getMock();
$testable = new Testable($dependencyMock);
Cela rend le refactoring avec un IDE beaucoup plus facile
Mon explication pour la réponse de Shakil:
J'ai eu le même problème.
Suite au livre de recettes symfony2, j'ai créé une maquette de
\Doctrine\Common\Persistence\ObjectManager
et mon constructeur de services était:
use Doctrine\ORM\EntityManager;
/* ... */
public function __construct(EntityManager $oEm)
{
$this->oEm = $oEm;
}
J'ai donc créé mon test unitaire (suivant le livre de recettes symfony2):
$entityManager = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager')
->disableOriginalConstructor()
->getMock();
$myService = new MyService($entityManager);
Ensuite, j'ai eu l'erreur:
Argument 1 passed to MyService::__construct() must be an instance of Doctrine\ORM\EntityManager, instance of Mock_ObjectManager_f4068b7f given
Premièrement, je pensais que ce type d'indication était incompatible avec les tests unitaires, car une instance fictive était passée au constructeur au lieu d'une instance d'EntityManager.
Donc, après quelques recherches, la classe Mock_ObjectManager_f4068b7f est en fait une classe dynamique étendant la classe de votre maquette (dans mon cas Doctrine\ORM\EntityManager), donc le type d'indication est pas de problème et fonctionne bien.
Ma solution a été de créer une maquette de Doctrine\ORM\EntityManager au lieu de \ Doctrine\Common\Persistence\ObjectManager:
$entityManager = $this->getMockBuilder('\Doctrine\ORM\EntityManager')
->disableOriginalConstructor()
->getMock();
$myService = new MyService($entityManager);
Je ne fais que commencer par les tests unitaires, vous pouvez donc trouver mon explication évidente: p