php - Doctrine Lazy Loading in Symfony Test environment -


i have written quite complicated class, on want test functional aspects.

therefore use webtestcase symfony, , test against self-implemented import, in rely on doctrine's lazy loading. want import data new rows, works fine in both environments, or update existing data. in latter case want load given package, , catalogue (with lazy loading).

this part works fine in dev-environment, tests fail in testing-environment. using symfony2 (standard edition). here can see test using

<?php namespace sulu\bundle\translatebundle\tests\translate;  use sulu\bundle\corebundle\tests\databasetestcase; use sulu\bundle\translatebundle\translate\import;  class importtest extends databasetestcase {     /**      * @var import      */     protected $import;      /**      * @var array      */     protected static $entities;      public function setup()     {         $this->setupschema();          $this->import = new import(self::$em);     }      public function teardown()     {         parent::teardown();         self::$tool->dropschema(self::$entities);     }      public function setupschema()     {         self::$entities = array(             self::$em->getclassmetadata('sulu\bundle\translatebundle\entity\catalogue'),             self::$em->getclassmetadata('sulu\bundle\translatebundle\entity\code'),             self::$em->getclassmetadata('sulu\bundle\translatebundle\entity\location'),             self::$em->getclassmetadata('sulu\bundle\translatebundle\entity\package'),             self::$em->getclassmetadata('sulu\bundle\translatebundle\entity\translation'),         );          self::$tool->createschema(self::$entities);     }      public function testxliff()     {         // test usual import         $this->import->setfile(__dir__ . '/../fixtures/import.xliff');         $this->import->setname('import');         $this->import->setformat(import::xliff);         $this->import->setlocale('de');         $this->import->execute();          $package = self::$em->getrepository('sulutranslatebundle:package')->find(1);         $this->assertequals(1, $package->getid());         $this->assertequals('import', $package->getname());          $catalogue = self::$em->getrepository('sulutranslatebundle:catalogue')->find(1);         $this->assertequals(1, $catalogue->getid());         $this->assertequals('de', $catalogue->getlocale());          $codes = self::$em->getrepository('sulutranslatebundle:code')->findall();         $this->assertequals(1, $codes[0]->getid());         $this->assertequals('sulu.great', $codes[0]->getcode());         $this->assertequals(true, $codes[0]->getbackend());         $this->assertequals(true, $codes[0]->getfrontend());         $this->assertequals(null, $codes[0]->getlength());         $this->assertequals(2, $codes[1]->getid());         $this->assertequals('sulu.open', $codes[1]->getcode());         $this->assertequals(true, $codes[1]->getbackend());         $this->assertequals(true, $codes[1]->getfrontend());         $this->assertequals(null, $codes[1]->getlength());          $translations = self::$em->getrepository('sulutranslatebundle:translation')->findall();         $this->assertequals('sulu ist toll!', $translations[0]->getvalue());         $this->assertequals('sulu ist opensource!', $translations[1]->getvalue());          // test new import         $this->import->setfile(__dir__ . '/../fixtures/import_better.xliff');         $this->import->setname('import update');         $this->import->setformat(import::xliff);         $this->import->setlocale('de');         $this->import->setpackageid(1);         $this->import->execute();          $package = self::$em->getrepository('sulutranslatebundle:package')->find(1);         $this->assertequals(1, $package->getid());         $this->assertequals('import update', $package->getname());          $catalogue = self::$em->getrepository('sulutranslatebundle:catalogue')->find(1);         $this->assertequals(1, $catalogue->getid());         $this->assertequals('de', $catalogue->getlocale());          $codes = self::$em->getrepository('sulutranslatebundle:code')->findall();         $this->assertequals(1, $codes[0]->getid());         $this->assertequals('sulu.great', $codes[0]->getcode());         $this->assertequals(true, $codes[0]->getbackend());         $this->assertequals(true, $codes[0]->getfrontend());         $this->assertequals(null, $codes[0]->getlength());         $this->assertequals(2, $codes[1]->getid());         $this->assertequals('sulu.open', $codes[1]->getcode());         $this->assertequals(true, $codes[1]->getbackend());         $this->assertequals(true, $codes[1]->getfrontend());         $this->assertequals(null, $codes[1]->getlength());         $this->assertequals('sulu.very.great', $codes[2]->getcode());         $this->assertequals(true, $codes[2]->getbackend());         $this->assertequals(true, $codes[2]->getfrontend());         $this->assertequals(null, $codes[2]->getlength());         $this->assertequals('sulu.even.open', $codes[3]->getcode());         $this->assertequals(true, $codes[3]->getbackend());         $this->assertequals(true, $codes[3]->getfrontend());         $this->assertequals(null, $codes[3]->getlength());          $translations = self::$em->getrepository('sulutranslatebundle:translation')->findall();         $this->assertequals('sulu ist wirklich toll!', $translations[0]->getvalue());         $this->assertequals('sulu ist opensource!', $translations[1]->getvalue());         $this->assertequals('sulu ist sehr toll!', $translations[2]->getvalue());         $this->assertequals('sulu ist sogar opensource!', $translations[3]->getvalue());     } } 

and here can see function causing problem:

public function execute() {     // correct loader according format     $loader = null;     switch ($this->getformat()) {         case self::xliff:             $loader = new xlifffileloader();             break;     }      $newcatalogue = true;     if ($this->getpackageid() == null) {         // create new package , catalogue import         $package = new package();         $catalogue = new catalogue();         $catalogue->setpackage($package);         $this->em->persist($package);         $this->em->persist($catalogue);     } else {         // load given package , catalogue         $package = $this->em->getrepository('sulutranslatebundle:package')             ->find($this->getpackageid());          if (!$package) {             // if given package not existing throw exception             throw new packagenotfoundexception($this->getpackageid());         }          // find catalogue package matching given locale         $catalogue = null;         foreach ($package->getcatalogues() $packagecatalogue) {             /** @var $packagecatalogue catalogue */             if ($packagecatalogue->getlocale() == $this->getlocale()) {                 $catalogue = $packagecatalogue;                 $newcatalogue = false;             }         }          // if no catalogue found create new 1         if ($newcatalogue) {             $catalogue = new catalogue();             $catalogue->setpackage($package);             $this->em->persist($catalogue);         }     }      $package->setname($this->getname());     $catalogue->setlocale($this->getlocale());      // load file, , create new code/translation combination every message     $filecatalogue = $loader->load($this->getfile(), $this->getlocale());     foreach ($filecatalogue->all()['messages'] $key => $message) {         // check if code existing in current catalogue         if (!$newcatalogue && ($translate = $catalogue->findtranslation($key))) {             // update old code , translate             $translate->setvalue($message);         } else {             // create new code , translate             $code = new code();             $code->setpackage($package);             $code->setcode($key);             $code->setbackend(true);             $code->setfrontend(true);              $translate = new translation();             $translate->setcode($code);             $translate->setvalue($message);             $translate->setcatalogue($catalogue);              $this->em->persist($code);             $this->em->flush(); //fixme no flush in between, if possible             $this->em->persist($translate);         }     }      // save changes database     $this->em->flush(); } 

the problem line try catalogues package doesn't return anything. when debug can see package loaded, , catalogues-property persistentcollection, seems have arraycollection containing element (which not in _elements-array yet). following screenshot explains better:

enter image description here

edit: think problem related caching mechanism. if row existent before executing test, data read. otherwise not, tried delete result cache in following snippet:

public function testxliff() {     $cachedriver = self::$em->getconfiguration()->getresultcacheimpl();      // test usual import     $this->import->setfile(__dir__ . '/../fixtures/import.xliff');     $this->import->setname('import');     $this->import->setformat(import::xliff);     $this->import->setlocale('de');     $this->import->execute();      $cachedriver->deleteall();      // test new import     $this->import->setfile(__dir__ . '/../fixtures/import_better.xliff');     $this->import->setname('import update');     $this->import->setformat(import::xliff);     $this->import->setlocale('de');     $this->import->setpackageid(1);     $this->import->execute();      $cachedriver->deleteall();      // test new import new language code     $this->import->setfile(__dir__ . '/../fixtures/import.xliff');     $this->import->setname('import');     $this->import->setformat(import::xliff);     $this->import->setlocale('en');     $this->import->execute(); } 

edit2: managed tests running, in opinion dirty workaround... if clear "cache" $em->clear() results correct. of course have debugged problem, , realized objects identitymap-field in entitymanager used, contain initialized objects. collections have initialized-flag set on true, lazy loading part not executed. bug?


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

javascript - addthis share facebook and google+ url -

ios - Show keyboard with UITextField in the input accessory view -