php - Zend Framework 2: How to include Doctrine2 support in unit testing with phpunit? -


after further research, i'm rephrasing question: how mock doctrine2's entity manager unit testing, particularly in controllers? essentially, need go through unit tests , replace related mocking tablegateway doctrine2's entity manager.


(original post)

some time ago went through official zf2 getting started tutorial version 2.1 , completed it, went through additional tutorial concerning unit testing. http://framework.zend.com/manual/2.1/en/user-guide/overview.html http://framework.zend.com/manual/2.1/en/tutorials/unittesting.html

following completion of tutorials, concluded zend_db not handle application needs elegantly , started looking integrating , using doctrine 2 zend framework 2. struggled find examples , found following tutorial start. http://www.jasongrimes.org/2012/01/using-doctrine-2-in-zend-framework-2/

it here got hung wanted include doctrine 2 changes unit testing couldn't figure out how. after many days of fruitless research, put project away sometime , coming it. found decent tutorial subject concerns zf1 structure different. http://www.zendcasts.com/unit-testing-doctrine-2-entities/2011/02/

however, fresh eyes , comparing sample zf2 files files associated zf1 framework, see @ least need set doctrine entity manager in phpunit bootstrap file , call in controller tests correctly.

currently, when run phpunit, following error:

there 1 failure:  1) albumtest\controller\albumcontrollertest::testeditactionredirectsaftervalidpost expectation failed method name equal <string:find> when invoked 1 time(s). method expected called 1 times, called 0 times. 

in relevant part of test method, have:

    //$albumtablemock = $this->getmockbuilder('album\models\albumtable')  // zend_db     $albumtablemock = $this->getmockbuilder('album\entity\album')                            ->disableoriginalconstructor()                            ->getmock(); 

(i'm not sure if 'album\entity\album' correct here understanding because of doctrine 2, i'm no longer using 'album\models\album' or 'album\models\albumtable' created in initial tutorial.)

in albumcontroller, relevant portion of code here:

    // album specified id.  exception thrown     // if cannot found, in case go index page.     try {         //$album = $this-> getalbumtable()->getalbum($id); // zend_db         $album = $this->getentitymanager()->find('album\entity\album', $id); // doctrine     } 

so main question here how set phpunit bootstrap file include doctrine2?


(addendum) i'll circle around above scenario i'm trying mock entity manager tests , i've commented out above getmocks in controller test down basics. i've gotten basic test set album\entity\album think bootstrapping ok i'm failing tests trying access database controller when using $this->dispatch(), don't want.

phpunit failure:

1) albumtest\controller\albumcontrollertest::testindexactioncanbeaccessed pdoexception: sqlstate[hy000] [1045] access denied user 'username'@'localhost' (using password: yes) 

i don't have user explicitly defined anywhere i'm guessing config file isn't being found or loaded want mock database connection anyway.

here's test bootstrap:

<?php  namespace albumtest;  use zend\loader\autoloaderfactory; use zend\mvc\service\servicemanagerconfig; use zend\servicemanager\servicemanager; //use doctrineormmoduletest\framework\testcase; //use doctrine\tests\mocks; use runtimeexception;  error_reporting(e_all | e_strict); chdir(__dir__);  // set timezone or phpunit reports error date_default_timezone_set('america/chicago');  /**  * test bootstrap, setting autoloading  */ class bootstrap {     protected static $servicemanager;     protected static $em; // doctrine       public static function init()     {         $zf2modulepaths = array(dirname(dirname(__dir__)));         if (($path = static::findparentpath('vendor'))) {             $zf2modulepaths[] = $path;         }         if (($path = static::findparentpath('module')) !== $zf2modulepaths[0]) {             $zf2modulepaths[] = $path;         }          static::initautoloader();          // use modulemanager load module , it's dependencies         $config = array(             'module_listener_options' => array(                 'module_paths' => $zf2modulepaths,             ),             'modules' => array(                 'doctrinemodule',                 'doctrineormmodule',                 'album'             )         );          $servicemanager = new servicemanager(new servicemanagerconfig());         $servicemanager->setservice('applicationconfig', $config);         $servicemanager->get('modulemanager')->loadmodules();         static::$servicemanager = $servicemanager;         static::$em = self::getentitymanager($servicemanager); // doctrine     }       public static function getservicemanager()     {         return static::$servicemanager;     }       public static function getentitymanager($servicemanager)     {         return $servicemanager->get('doctrine\orm\entitymanager');     }       protected static function initautoloader()     {         $vendorpath = static::findparentpath('vendor');          $zf2path = getenv('zf2_path');         if (!$zf2path) {             if (defined('zf2_path')) {                 $zf2path = zf2_path;             } else {                 if (is_dir($vendorpath . '/zf2/library')) {                     $zf2path = $vendorpath . '/zf2/library';                 }             }         }          if (!$zf2path) {             throw new runtimeexception('unable load zf2. run `php composer.phar install` or define zf2_path environment variable.');         }          include $zf2path . '/zend/loader/autoloaderfactory.php';         autoloaderfactory::factory(array(             'zend\loader\standardautoloader' => array(                 'autoregister_zf' => true,                 'namespaces' => array(                     __namespace__ => __dir__ . '/' . __namespace__,                 ),             ),         ));     }       protected static function findparentpath($path)     {         // function traverses working directory         // until finds parent of named path         // (used find 'vendor' parent in initautoloader).         $dir = __dir__;         $previousdir = '.';         while (!is_dir($dir . '/' . $path)) {             $dir = dirname($dir);             if ($previousdir === $dir) return false;             $previousdir = $dir;         }         return $dir . '/' . $path;     } }  bootstrap::init(); 

here's entity test (to prove doctrine bootstrapped correctly):

<?php  namespace albumtest\entity;  use album\entity\album; use phpunit_framework_testcase;   class albumtest extends phpunit_framework_testcase {     public function testalbuminitialstate() {          $album = new album();          $this->assertnull($album->artist, '"artist" should null');         $this->assertnull($album->id, '"id" should null');         $this->assertnull($album->title, '"title" should null');     } } 

and here's relevant portions of controller test:

<?php  namespace albumtest\controller;  //use album\models\album; use album\entity\album; use zend\test\phpunit\controller\abstracthttpcontrollertestcase; use zend\db\resultset\resultset; //use phpunit_framework_testcase;   class albumcontrollertest extends abstracthttpcontrollertestcase {     protected $traceerror = true;      public function setup()     {         // need mock entity manager doctrine use         $this->em = $this->getmock('entitymanager', array('persist', 'flush', 'find','getclassmetadata','getrepository'));         $this->em             ->expects($this->any())             ->method('persist')             ->will($this->returnvalue(true));         $this->em             ->expects($this->any())             ->method('flush')             ->will($this->returnvalue(true));         $this->em             ->expects($this->any())             ->method('find')             ->will($this->returnvalue(true));         $this->em             ->expects($this->any())             ->method('getrepository')             ->will($this->returnvalue(true));         $this->em             ->expects($this->any())             ->method('getclassmetadata')             ->will($this->returnvalue((object)array('name' => 'aclass')));         $this->doctrine = $this->getmock('doctrine', array('getentitymanager'));         $this->doctrine             ->expects($this->any())             ->method('getentitymanager')             ->will($this->returnvalue($this->em));          $this->setapplicationconfig(             include __dir__ . '../../../../../../config/application.config.php'         );         parent::setup();     }       public function testindexactioncanbeaccessed()     {         //$albumtablemock = $this->getmockbuilder('album\models\albumtable')         $albumtablemock = $this->getmockbuilder('album\entity\album')                                ->disableoriginalconstructor()                                ->getmock();          $albumtablemock->expects($this->once())                        //->method('fetchall')                        ->method('findall')                        ->will($this->returnvalue(array()));          $servicemanager = $this->getapplicationservicelocator();         $servicemanager->setallowoverride(true);         $servicemanager->setservice('album\entity\album', $albumtablemock);           $this->dispatch('/album');         $this->assertresponsestatuscode(200);          $this->assertmodulename('album');         $this->assertcontrollername('album\controller\album');         $this->assertcontrollerclass('albumcontroller');         $this->assertmatchedroutename('album');     } 

i think i've set basics of entitymanager mock although references based off of had mocked fakerepository() object returned the getrepository() method wasn't shown. also, i'm not sure how call mocked entitymanager in test in place of original getmock call.

you need use generictestsdatabasetestcase database test cases , need provide mysql dump file in xml format dataset in database test case class. due this, during unit testing, application not query on actual database, instead it'll query on mysql xml dump. other things exception/error in doctrine entity if there not matched columns etc.. work is. in short, due dataset [database xml dump file] doctine fire query on xml dataset file instead of actual database.


Comments

Popular posts from this blog

c++ - OpenCV Error: Assertion failed <scn == 3 ::scn == 4> in unknown function, -

php - render data via PDO::FETCH_FUNC vs loop -

The canvas has been tainted by cross-origin data in chrome only -