Doctrine orm 在每次测试后,不使用数据固定装置,对数据库条目执行Nuke/Delete/Truncate操作
我有以下测试用例:Doctrine orm 在每次测试后,不使用数据固定装置,对数据库条目执行Nuke/Delete/Truncate操作,doctrine-orm,phpunit,symfony-3.4,Doctrine Orm,Phpunit,Symfony 3.4,我有以下测试用例: namespace Tests\AppBundle\Repository; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use AppBundle\Entity\ContactEmail; class ContactEmailTest extends KernelTestCase { /** * @var \Doctrine\ORM\EntityManager */ privat
namespace Tests\AppBundle\Repository;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use AppBundle\Entity\ContactEmail;
class ContactEmailTest extends KernelTestCase
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* {@inheritDoc}
*/
protected function setUp()
{
$kernel = self::bootKernel();
$this->entityManager = $kernel->getContainer()
->get('doctrine')
->getManager();
}
public function testInsert()
{
$email="jdoe@example.com";
/**
* @var Appbundle\Repository\ContactEmailRepository
*/
$repository=$this->entityManager->getRepository(ContactEmail::class);
$contactEmailEntity=$repository->addEmail($email);
$this->assertEquals($contactEmailEntity->getEmail(),$email);
$emailSearched=$repository->findByEmail($email);
if(empty($emailSearched)){
$this->fail('No email has been found');
}
$this->assertEquals($email,$emailSearched[0]);
}
/**
* expectException(Doctrine\DBAL\Exception\UniqueConstraintViolationException)
*/
public function testInsertDucplicate()
{
$email="jdoe@example.com";
/**
* @var Appbundle\Repository\ContactEmailRepository
*/
$repository=$this->entityManager->getRepository(ContactEmail::class);
// We purpocely ingoring the returned value
$repository->addEmail($email);
$repository->addEmail($email);
}
/**
* {@inheritDoc}
*/
protected function tearDown()
{
parent::tearDown();
$this->entityManager->close();
$this->entityManager = null; // avoid memory leaks
}
}
我尝试测试自定义存储库的以下方法:
namespace AppBundle\Repository;
use AppBundle\Entity\ContactEmail;
/**
* ContactEmailRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ContactEmailRepository extends \Doctrine\ORM\EntityRepository
{
/**
* Adding an Email to the database
* @param String $email
*
* @throws Doctrine\DBAL\Exception\UniqueConstraintViolationException
*
* @return AppBundle\Entity\ContactEmail
*/
public function addEmail($email)
{
$emailToAdd=new ContactEmail();
$emailToAdd->setEmail($email);
/**
* @var Doctrine\ORM\EntityManager
*/
$em=$this->getEntityManager();
$em->persist($emailToAdd);
$em->flush();
return $emailToAdd;
}
}
那么,在每次测试之后,我将如何核化所有数据库条目,以便拥有一个干净实例的新的空数据库呢
我之所以这么问,是因为我不想让以前的测试留下的条目破坏我的测试。一个好办法是使用这个网络中提到的逻辑。为此,将
设置方法更改为:
//namespace definition and use classes from other namespaces
use Doctrine\ORM\Tools\SchemaTool;
//Class definition etc etc...
protected function setUp()
{
$kernel = self::bootKernel();
$this->entityManager = $kernel->getContainer()
->get('doctrine')
->getManager();
//In case leftover entries exist
$schemaTool = new SchemaTool($this->entityManager);
$metadata = $this->entityManager->getMetadataFactory()->getAllMetadata();
// Drop and recreate tables for all entities
$schemaTool->dropSchema($metadata);
$schemaTool->createSchema($metadata);
}
如您所见,您可以通过$this->entityManager->getMetadataFactory()->getAllMetadata()获取模式信息代码>链方法调用,然后使用chematool以编程方式清除和创建模式
另外一个好方法是为测试使用单独的数据库。在我的例子中,我将以下配置放入config test.yml
doctrine:
dbal:
dbname: '%database_name%-test'
这会自动在数据库名称后面添加一个-test
结尾,这样,如果我开发的数据库名为mydb
,那么测试数据库将是mydb test
,这样你就可以随心所欲地执行测试,而不用担心破坏开发工作流程。也许我在你的代码中漏掉了一些应该做的东西让它对我来说更明显,但我很好奇为什么你想要避免使用数据装置?我不是在避免它,只是在我的测试用例中,我不需要数据装置。如果您更仔细地观察,您将看到我测试了数据插入,因此不需要数据装置。我只是放置了数据夹具参考,以便将我的问题与其他问题区分开来。您可以在setUp()
或tearDown()
或两者上重置数据库。例如,让快照文件系统重置数据库。