Doctrine2.2 (sqlite using memory) 使用 OrmTestCase 和 phpUnit TroubleShoot

Posted

技术标签:

【中文标题】Doctrine2.2 (sqlite using memory) 使用 OrmTestCase 和 phpUnit TroubleShoot【英文标题】:Doctrine2.2 (sqlite using memory) using OrmTestCase with phpUnit TroubleShoot 【发布时间】:2012-04-03 01:26:42 【问题描述】:

我目前正在尝试使用 phpUnit 测试我的学说 2.2 对象,我正在使用可以在here 找到的学说扩展。

这是我所有的 phpUnit TestClass 扩展的基类。

<?php
use DoctrineExtensions\PHPUnit\Event\EntityManagerEventArgs,
    DoctrineExtensions\PHPUnit\OrmTestCase,
    Doctrine\ORM\Tools\SchemaTool,
    Doctrine\Common\EventManager,
    Doctrine\ORM\Tools\Setup,
    Doctrine\ORM\EntityManager;

class SchemaSetupListener 
    public function preTestSetUp(EntityManagerEventArgs $eventArgs) 
        $em = $eventArgs->getEntityManager();
        $schemaTool = new SchemaTool($em);
        $cmf = $em->getMetadataFactory();
        $classes = $cmf->getAllMetadata();
        $schemaTool->dropDatabase();
        $schemaTool->createSchema($classes);
    


class EntityFunctionalTest extends OrmTestCase 

    protected function createEntityManager() 
        $config = Setup::createXMLMetadataConfiguration(array(DIR_XML_SCHEMA), true); // dev mode true
        $conn = array('driver' => 'pdo_sqlite', 'path' =>  DIR_TEST_SUITE_ROOT . 'test.db');
        $conn = array('driver' => 'pdo_sqlite', 'memory' => true);
        $eventManager = new EventManager();
        $eventManager->addEventListener(array("preTestSetUp"), new SchemaSetupListener());
        return Doctrine\ORM\EntityManager::create( $conn, $config, $eventManager);
    

    protected function getDataSet() 
        return $this->createFlatXmlDataSet(DIR_XML_TEST_DATA . 'db.boot.strap.test.flat.xml');
    

    protected function tearDown()
        $entityManager = $this->getEntityManager();
        $entityManager->flush();
        $entityManager->getConnection()->getConfiguration()->setSQLLogger(null);;
        $entityManager->close();
    

    public function getSystemUser()
        return $this->getEntityManager()->createQuery('select u from User u where u.id = 1')->getSingleResult();
    


?>

当我在下面注释掉以下内容时,sqlite 不会在内存中创建其数据库,但一切正常,但速度很慢。

$conn = array('driver' => 'pdo_sqlite', 'path' =>  DIR_TEST_SUITE_ROOT . 'test.db');
//$conn = array('driver' => 'pdo_sqlite', 'memory' => true);

当我取消注释该行并尝试使用内存中的 slqlite 数据库运行测试时,只有第一个测试函数从 getDataSet() 方法获取数据(当我使用 sqlite 数据库运行时,一切都很好)。

为什么 getDataSet() 方法只适用于第一个测试方法?

这是我在命令行中运行测试的输出:

C:\TestSuite\phpUnit\testsuites>phpUnit --configuration al

lTests.xml
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from C:\TestSuite\phpUnit\testsuites\al
lTests.xml

.E

Time: 1 second, Memory: 16.00Mb

There was 1 error:

1) UserTest::testId
Doctrine\ORM\NoResultException: No result was found for query although at least
one row was expected.

C:\Program Files (x86)\PHP\PEAR\Doctrine\ORM\AbstractQuery.php:491
C:\TestSuite\phpUnit\testsuites\classes\entities\EntityFun
ctionalTest.php:43
C:\TestSuite\phpUnit\testsuites\classes\entities\UserTest.
php:60
C:\Program Files (x86)\PHP\phpunit:46

FAILURES!
Tests: 2, Assertions: 8, Errors: 1.

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,解决方案是在测试之间共享实体管理器:

protected static $em = null;

public static function setUpBeforeClass()

    $isDevMode = true;
    $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/../src"), $isDevMode, null, null, false);

    $connectionOptions = array('driver' => 'pdo_sqlite', 'memory' => true);

    // obtaining the entity manager
    self::$em =  EntityManager::create($connectionOptions, $config);

    $schemaTool = new SchemaTool(self::$em);

    $cmf = self::$em->getMetadataFactory();
    $classes = $cmf->getAllMetadata();

    $schemaTool->dropDatabase();
    $schemaTool->createSchema($classes);



public static function tearDownAfterClass()

    self::$em = NULL;


protected function createEntityManager()



    return self::$em;

【讨论】:

【参考方案2】:

除了@Zedenek Machek 所说的: 从松散耦合测试的角度来看,应避免共享固定装置

在测试之间共享固定装置会降低测试的价值,这一点再怎么强调也不为过。潜在的设计问题是对象不是松散耦合的。与在运行时创建测试之间的依赖关系并忽略改进设计的机会相比,解决底层设计问题然后使用存根编写测试(参见第 9 章)将获得更好的结果。

见https://phpunit.de/manual/current/en/fixtures.html#fixtures.sharing-fixture.examples.DatabaseTest.php

【讨论】:

以上是关于Doctrine2.2 (sqlite using memory) 使用 OrmTestCase 和 phpUnit TroubleShoot的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine2 Mapping:2 个字段映射到一个字段(ManyToOne)

SQlite不更新记录

2016年应该使用SQLite的5大原因

如何将SQLite数据库备份到SD卡?

SQLite:插入身份列

iOS真机测试友盟碰到错误linker command failed with exit code 1 (use -v to see invocation) 百度地图的检索失败 sqlite 错误