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' 用法。此外,如果我在我的方法中违反了任何最佳实践,或者我需要重新考虑我的设计,我想听听。
说清楚我想:
- 生成带有@Entity(可能还有其他)注释的class,我已经在这样做了
- 让学说更新架构以仅包含这些 classes
- 这些 classes 的映射在下次执行时可用
感谢您的想法。
很难找到在独立 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) 具体映射
为此,您可以:
- 使用学说 EntityGenerator (example).
生成实体
- 通过将现有实体添加到 your whitelist 来加载它们(或排除那些您不想测试的实体)。
注意如果您需要生成它们,您需要在实体不存在时将测试标记为已跳过。
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();
}
希望对您有所帮助。
我目前正在开发一个 Symfony 3 包,它具有生成一些样板代码的功能。我想通过使用 phpunit 来测试正确性。为此,我认为最好生成一些测试用例(其中将有 classes 的源代码,其中将具有 @Entity 注释)并让 Doctrine 仅使用实体更新测试环境的数据库执行测试所需的。之后可以再次安全地删除相应的表。
但我不知道执行此操作的简单方法。由于我的包可能有一天会安装在一个不完整的项目上,我希望不必为了测试这个包而更新整个模式,当测试甚至可能失败时。
我知道 Doctrine 的 Schema
class 但我想知道是否有更实用的解决方案?问题是你可以用它创建表等,但我想那时不会有任何映射?
Google 不是很有帮助,所以我怀疑我在这里偏离了 'normal' 用法。此外,如果我在我的方法中违反了任何最佳实践,或者我需要重新考虑我的设计,我想听听。
说清楚我想:
- 生成带有@Entity(可能还有其他)注释的class,我已经在这样做了
- 让学说更新架构以仅包含这些 classes
- 这些 classes 的映射在下次执行时可用
感谢您的想法。
很难找到在独立 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) 具体映射
为此,您可以:
- 使用学说 EntityGenerator (example). 生成实体
- 通过将现有实体添加到 your whitelist 来加载它们(或排除那些您不想测试的实体)。
注意如果您需要生成它们,您需要在实体不存在时将测试标记为已跳过。
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();
}
希望对您有所帮助。