Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 26-05-2015 11:43:00

amelie
Membre
Lieu: Marseille
Date d'inscription: 05-02-2013
Messages: 113
Site web

[Résolu] Tests unitaires et injections de dépendances

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 :

Code:

[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 :

Code:

[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 smile ) mais ça se complique ensuite dans mes petits tests unitaires ...

Voici la tête de mon test :


Code:

[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 :

Code:

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 smile !

Dernière modification par amelie (26-05-2015 15:58:47)

Hors ligne

 

#2 26-05-2015 11:59:27

tdutrion
Administrateur
Lieu: Dijon, Paris, Edinburgh
Date d'inscription: 23-12-2009
Messages: 614
Site web

Re: [Résolu] Tests unitaires et injections de dépendances

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 !

Hors ligne

 

#3 26-05-2015 12:31:36

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Résolu] Tests unitaires et injections de dépendances

Hello comme l'a dit Théocrite ça devrait fonctionner. Par contre ça m'étonne que ça fonctionne d'instancier une interface.

Hors ligne

 

#4 26-05-2015 14:22:10

amelie
Membre
Lieu: Marseille
Date d'inscription: 05-02-2013
Messages: 113
Site web

Re: [Résolu] Tests unitaires et injections de dépendances

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 smile.
J'ai essayé comme ça :

Code:

[lang=php]
$listService = $this->getMock('ListeServiceInterface');
$this->assertTrue($listService instanceof ListeServiceInterface);
$this->controller = new SitesController($listService);

mais :

Code:

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

sad

Hors ligne

 

#5 26-05-2015 14:42:23

amelie
Membre
Lieu: Marseille
Date d'inscription: 05-02-2013
Messages: 113
Site web

Re: [Résolu] Tests unitaires et injections de dépendances

Trouvé smile

Il fallait mettre le namespace complet dans getMock smile
Thanks big_smile !!!

Hors ligne

 

#6 26-05-2015 16:00:06

amelie
Membre
Lieu: Marseille
Date d'inscription: 05-02-2013
Messages: 113
Site web

Re: [Résolu] Tests unitaires et injections de dépendances

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 smile

Hors ligne

 

#7 27-05-2015 00:10:11

tdutrion
Administrateur
Lieu: Dijon, Paris, Edinburgh
Date d'inscription: 23-12-2009
Messages: 614
Site web

Re: [Résolu] Tests unitaires et injections de dépendances

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

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages