doctrine:schema:update 可以限制为可用实体的子集吗?

Can doctrine:schema:update be restricted to a subset of available entities?

我目前正在开发一个 Symfony 3 包,它具有生成一些样板代码的功能。我想通过使用 phpunit 来测试正确性。为此,我认为最好生成一些测试用例(其中将有 classes 的源代码,其中将具有 @Entity 注释)并让 Doctrine 仅使用实体更新测试环境的数据库执行测试所需的。之后可以再次安全地删除相应的表。

但我不知道执行此操作的简单方法。由于我的包可能有一天会安装在一个不完整的项目上,我希望不必为了测试这个包而更新整个模式,当测试甚至可能失败时。

我知道 Doctrine 的 Schema class 但我想知道是否有更实用的解决方案?问题是你可以用它创建表等,但我想那时不会有任何映射?

Google 不是很有帮助,所以我怀疑我在这里偏离了 'normal' 用法。此外,如果我在我的方法中违反了任何最佳实践,或者我需要重新考虑我的设计,我想听听。

说清楚我想:

感谢您的想法。

很难找到在独立 bundle/library 上使用原则进行数据库测试的良好做法。

那么,我给大家介绍一下我的使用方法:

1) 一个特定的数据库

为此,您可以创建特定的配置文件,包括您的数据库配置,这将与您的其他环境使用的不同,或者只是 define environment variables 在您的 phpunit 配置中。

为了在测试阶段创建一个临时数据库:

/**
 * Create database.
 */
public static function createDatabase($path)
{
    $config = [
        'driver'   => 'pdo_mysql',
        'host'     => '127.0.0.1',
        'user'     => 'forge',
        'password' => 'forge',
    ];

    $tmpConnection = \Doctrine\DBAL\DriverManager::getConnection($config);

    // If the db exists, do nothing
    if (in_array('db_name', $tmpConnection->getSchemaManager()->listDatabases())) {
        return;
    }

    // Create the db
    $tmpConnection->getSchemaManager()->createDatabase($GLOBALS['db_name']);

    $tmpConnection->close();
}

2) 具体映射

为此,您可以:

注意如果您需要生成它们,您需要在实体不存在时将测试标记为已跳过。

3) 特定架构

您需要重新生成数据库连接(临时),在测试开始时创建架构并在测试结束时删除它。

可以在 lite 中恢复最后两个阶段 class:

use Doctrine\DBAL\DriverManager;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\ORM\Tools\Setup;

/**
 * Database.
 */
class Db
{
    /** @var EntityManager */
    private $entityManager;

    /**
     * Create db schema.
     */
    public function createSchema() 
    {
        // Location(s) of your mapping
        $mappingPaths = ['Acme/Path/To/Entities', 'Acme/Second/Path/To/Entities', ...];

        // Db config, should be loaded from config files as previously said
        $config = [
            'dbname'   => 'project_test'
            'driver'   => 'pdo_mysql',
            'host'     => 127.0.0.1,
            'user'     => 'forge',
            'password' => 'forge',
        ];

        // Configure and load your mapping
        $metadataConfiguration = Setup::createAnnotationMetadataConfiguration($mappingPaths, true, null, null, false);

        // Create the EntityManager instance
        $em = EntityManager::create($config, $metadataConfiguration);

        $tool = new SchemaTool($em);
        $metadata = $em->getMetaDataFactory()->getAllMetaData();

        // Drop an eventual existing schema
        $tool->dropSchema($metadata);  

        // Create the new schema 
        $tool->createSchema($metadata);

        $this->em = $em;
    }

    /**
     * @return EntityManager
     */
    public function getEntityManager()
    {
        return $this->em;
    }
}

用法:

public function setUp()
{   
    // Create the schema
    $db = new Db();
    $db->createSchema();

    // Enjoy
    $this->em = $db->getEntityManager();
}

希望对您有所帮助。