Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour à tous,
Voilà j'ai un controlleur qui s'appelle SitesController() qui me permet de gérer un ensemble de "sites" pour mon intranet.
Dans ce controlleur j'ai injecté une factory qui me permet après de gérer des listes après avoir fait un fetchAll dans ma tablegateway. Donc ça donne ça :
[lang=php] class SitesController extends AbstractActionController { protected $listService; public function __construct(ListeServiceInterface $listService) { $this->listService = $listService; } public function getListService(){ return $this->listService; } public function listAction() { try { $this->layout('layout/maintenance'); return new ViewModel(); } catch (\Exception $e) { throw new \Exception($e); } } etc...
Voici la tête de ma factory :
[lang=php] namespace Maintenance\Factory; use Maintenance\Controller\SitesController; use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; class SitesControllerFactory implements FactoryInterface { public function createService(ServiceLocatorInterface $serviceLocator) { $realServiceLocator = $serviceLocator->getServiceLocator(); $listService = $realServiceLocator->get('Maintenance\Service\ListeServiceInterface'); return new SitesController($listService); } }
Donc voilà j'ai ce $listService qui est envoyé à mon controlleur.
Jusque là rien de bien méchant, tout marche comme dans le meilleur des mondes avec mes listes (alors l'exemple n'est pas significatif car on ne voit pas les manipulations donc l'intérêt de mon injection mais c'est après dans le code et là c'est pas vraiment le souci ) mais ça se complique ensuite dans mes petits tests unitaires ...
Voici la tête de mon test :
[lang=php] class SitesControllerTest extends PHPUnit_Framework_TestCase { protected $controller; protected $request; protected $response; protected $routeMatch; protected $event; protected function setUp() { $serviceManager = Bootstrap::getServiceManager(); $this->controller = new SitesController(); $this->request = new Request(); $this->routeMatch = new RouteMatch(array('controller' => 'index')); $this->event = new MvcEvent(); $config = $serviceManager->get('Config'); $routerConfig = isset($config['router']) ? $config['router'] : array(); $router = HttpRouter::factory($routerConfig); $this->event->setRouter($router); $this->event->setRouteMatch($this->routeMatch); $this->controller->setEvent($this->event); $this->controller->setServiceLocator($serviceManager); } public function testListActionCanBeAccessed() { $this->routeMatch->setParam('action', 'list'); $result = $this->controller->dispatch($this->request); $response = $this->controller->getResponse(); $this->assertEquals(200, $response->getStatusCode()); }
Et pime ! je me prends l'erreur suivante :
PHPUnit 4.6.7 by Sebastian Bergmann and contributors. Configuration read from C:\wwwroot\intranet_new\module\Maintenance\tests\phpunit .xml.dist E Time: 421 ms, Memory: 11.00Mb There was 1 error: 1) MaintenanceTest\Controller\SitesControllerTest::testListActionCanBeAccessed Argument 1 passed to Maintenance\Controller\SitesController::__construct() must be an instance of Maintenance\Service\ListeServiceInterface, none given, called in C:\wwwroot\intranet_new\module\Maintenance\tests\MaintenanceTest\SitesControl lerTest.php on line 24 and defined C:\wwwroot\intranet_new\module\Maintenance\src\Maintenance\Controller\SitesContr oller.php:30 C:\wwwroot\intranet_new\module\Maintenance\tests\MaintenanceTest\SitesController Test.php:24 FAILURES! Tests: 1, Assertions: 0, Errors: 1.
Du coup comment je peux faire pour injecter mon ListeServiceInterface dans mon test ?
Merci à vous !
Dernière modification par amelie (26-05-2015 15:58:47)
Hors ligne
Bonjour,
Tu as la ligne suivante dans ton setup :
[lang=php]$this->controller = new SitesController();
Du coup il faut la modifier :
[lang=php]$this->controller = new SitesController($listService);
Il te faut donc un $listService à passer, et ça ce sera un mock qui te permet donc de créer un "faux objet" qui renvoi ce que tu attends de lui (ListeServiceInterface et toutes les méthodes incluses dans cette interface). Les objets implémentant cette interface étant testé unitairement de leur côté, c'est tout bon !
Hors ligne
Hello comme l'a dit Théocrite ça devrait fonctionner. Par contre ça m'étonne que ça fonctionne d'instancier une interface.
Hors ligne
Théocrite a écrit:
Bonjour,
Tu as la ligne suivante dans ton setup :Code:
[lang=php]$this->controller = new SitesController();Du coup il faut la modifier :
Code:
[lang=php]$this->controller = new SitesController($listService);Il te faut donc un $listService à passer, et ça ce sera un mock qui te permet donc de créer un "faux objet" qui renvoi ce que tu attends de lui (ListeServiceInterface et toutes les méthodes incluses dans cette interface). Les objets implémentant cette interface étant testé unitairement de leur côté, c'est tout bon !
Merci .
J'ai essayé comme ça :
[lang=php] $listService = $this->getMock('ListeServiceInterface'); $this->assertTrue($listService instanceof ListeServiceInterface); $this->controller = new SitesController($listService);
mais :
There was 1 failure: 1) MaintenanceTest\Controller\SitesControllerTest::testListActionCanBeAccessed Failed asserting that false is true. C:\wwwroot\intranet_new\module\Maintenance\tests\MaintenanceTest\SitesController Test.php:32
Hors ligne
Orkin a écrit:
Hello comme l'a dit Théocrite ça devrait fonctionner. Par contre ça m'étonne que ça fonctionne d'instancier une interface.
En injection ça passe
Hors ligne
En fait techniquement un mock est un objet (donc pas une interface), et du coup tu injectes bien un objet. Par contre tu lui dit de répondre ce que tu as envie et du coup si tu répoonds "mon nom de classe est ...Interface", quand on test si tu implémentes cette interface ça marche !
Hors ligne