1

我写了一个相当复杂的类,我想在上面测试一些功能方面。

因此,我使用 symfony 的 WebTestCase,并针对自我实现的导入进行测试,其中我依赖于学说的延迟加载。我想将数据作为新行导入,这在两种环境中都可以正常工作,或者更新已经存在的数据。在后一种情况下,我想加载给定的包,并获取目录(延迟加载)。

这部分在开发环境中运行良好,但在测试环境中测试失败。我正在使用 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,它似乎有一个包含一个元素的 ArrayCollection(它还没有在 _elements-array 中)。以下屏幕截图希望能更好地解释它:

在此处输入图像描述

编辑:我认为问题与缓存机制有关。如果在执行测试之前该行已经存在,则读取数据。否则不是,我已经尝试删除结果缓存,如下面的片段:

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-field中的对象,其中已经包含了初始化的对象。所以所有的集合都将 initialized-flag 设置为 true,因此不会执行延迟加载部分。那是一个错误吗?

4

0 回答 0