1

いくつかの機能面をテストしたい、非常に複雑なクラスを作成しました。

したがって、symfony の WebTestCase を使用し、doctrine の遅延読み込みに依存する自己実装のインポートに対してテストします。両方の環境で正常に機能する新しい行としてデータをインポートするか、既存のデータを更新したいと考えています。後者の場合、指定されたパッケージをロードし、カタログを取得します (遅延ロードを使用)。

この部分は開発環境では問題なく動作しますが、テスト環境ではテストが失敗します。symfony2 (標準版) を使用しています。ここで私が使用しているテストを見ることができます

<?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());
    }
}

そして、ここで私の問題を引き起こしている機能を見ることができます:

public function execute()
{
    // get correct loader according to format
    $loader = null;
    switch ($this->getFormat()) {
        case self::XLIFF:
            $loader = new XliffFileLoader();
            break;
    }

    $newCatalogue = true;
    if ($this->getPackageId() == null) {
        // create a new package and catalogue for the import
        $package = new Package();
        $catalogue = new Catalogue();
        $catalogue->setPackage($package);
        $this->em->persist($package);
        $this->em->persist($catalogue);
    } else {
        // load the given package and catalogue
        $package = $this->em->getRepository('SuluTranslateBundle:Package')
            ->find($this->getPackageId());

        if (!$package) {
            // If the given package is not existing throw an exception
            throw new PackageNotFoundException($this->getPackageId());
        }

        // find the catalogue from this package matching the given locale
        $catalogue = null;
        foreach ($package->getCatalogues() as $packageCatalogue) {
            /** @var $packageCatalogue Catalogue */
            if ($packageCatalogue->getLocale() == $this->getLocale()) {
                $catalogue = $packageCatalogue;
                $newCatalogue = false;
            }
        }

        // if no catalogue is found create a new one
        if ($newCatalogue) {
            $catalogue = new Catalogue();
            $catalogue->setPackage($package);
            $this->em->persist($catalogue);
        }
    }

    $package->setName($this->getName());
    $catalogue->setLocale($this->getLocale());

    // load the file, and create a new code/translation combination for every message
    $fileCatalogue = $loader->load($this->getFile(), $this->getLocale());
    foreach ($fileCatalogue->all()['messages'] as $key => $message) {
        // Check if code is already existing in current catalogue
        if (!$newCatalogue && ($translate = $catalogue->findTranslation($key))) {
            // Update the old code and translate
            $translate->setValue($message);
        } else {
            // Create new code and 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 all the changes to the database
    $this->em->flush();
}

問題は、パッケージからカタログを取得しようとする行が何も返さないことです。デバッグすると、パッケージがロードされていることがわかります。catalogues-property は PersistentCollection であり、要素 (_elements-array にはまだありません) を含む ArrayCollection があるようです。次のスクリーンショットは、うまくいけばそれをよりよく説明しています:

ここに画像の説明を入力

編集:問題はキャッシュメカニズムに関連していると思います。テストを実行する前に行がすでに存在する場合、データが読み取られます。そうでない場合は、次のスニペットのように結果キャッシュを削除しようとしました。

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 with 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:テストを実行するために管理しましたが、私の意見では、それは単なる回避策です... $em->clear() で「キャッシュ」をクリアすると、結果は正しいです。もちろん、私はこの問題をデバッグし、EntityManager の identityMap フィールドからのオブジェクトが使用されていることに気付きました。これには、既に初期化されたオブジェクトが含まれています。そのため、すべてのコレクションで初期化フラグが true に設定されているため、遅延読み込み部分は実行されません。それはバグですか?

4

0 に答える 0