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:
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
Post a Comment