每次测试后,Nuke / Delete / Truncate数据库条目,而无需使用数据固定装置

时间:2018-08-17 20:09:15

标签: 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
    */
   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;
  }
}

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

之所以问,是因为我不想从以前的测试中遗留下来的条目可能会破坏我的测试。

1 个答案:

答案 0 :(得分: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,因此您可以按照您不必担心破坏开发工作流程。