【问题标题】:Nuke/Delete/Truncate Database entries after each test WITHOUT the use of data fixtures每次测试后 Nuke/Delete/Truncate 数据库条目,而不使用数据夹具
【发布时间】:2019-01-24 21:37:42
【问题描述】:

我有以下测试用例:

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;
  }
}

那么在每次测试之后,我将如何对所有数据库条目进行核对,以便拥有一个全新的空数据库和一个干净的实例?

我问的原因是因为我不希望以前测试的剩余条目可能会破坏我的测试。

【问题讨论】:

  • 也许我在你的代码中遗漏了一些应该让我更清楚的东西,但我很好奇你为什么要避免使用数据夹具?
  • 我并没有避免它只是在我的测试用例中我不需要数据夹具。如果你仔细看,你会发现我测试了数据插入,因此不需要数据夹具。我只是把数据夹具引用为了区分我的问题和this 一个。
  • 您可以在 setUp()tearDown() 或两者上重置数据库。例如。有一个快照文件系统重置数据库。

标签: doctrine-orm phpunit symfony-3.4


【解决方案1】:

这样做的一个好方法是使用此网络中answer to "TearDown database after a phpUnitTest on a WebTestCase using DataFixtures" 中提到的逻辑。为此,将setUp 方法更改为:

   //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,因此您可以随意执行测试而不必担心破坏开发工作流程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    • 2013-11-08
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多