使用setUp方法在每个测试方法前清除数据库-Symfony5全面开发

您需要登录后才可观看此视频

为了更好的为您提供服务,请您登录后再查看本课程。

立即登录

现在我们有两个测试方法,testEntityManager()testEntityManagerQuery(),在两个测试方法中,都使用bootKernel()方法来启动内核准备容器,我们可以把启动内核准备容器的这个方法,统一放到一个setUp()方法中进行处理。

我们打开phpunit文档,在第四章,phpunit提供共享,建立基境的代码。在运行某个测试方法之前,会调用一个名叫setUp()的模板方法。setUp()是创建测试所用对象的地方,当测试方法进行结束后,不管是成功还是失败,都会调用另外一个方法tearDown()方法。tearDown()是清理测试所用对象的方法。

setUp()方法和tearDown()方法是对应的,我们添加setUp()方法,直接覆盖方法。在setUp()方法中,我们启动内核,注释19行代码,注释43行代码。bootKernel()方法最终的返回值是静态变量$kernel,所以我们直接可以在21行使用self::$kernel,另外$entitymanager我们可能在以后的测试中还会经常用到,所以我们把$entitymanager的获取也放到setUp()方法中。

我们把$entitymanager变量设置为私有属性,注释24行代码,修改代码,我们可以在setUp()方法中执行数据库的清除。,这样每次在执行测试时都会首先清空数据库,我这里就直接复制代码了,我们创建一个私有方法。

class EntityManagerTest extends KernelTestCase
{
    private $entitymanager;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->entitymanager = static::getContainer()->get('doctrine.orm.entity_manager');

        $this->truncateEntities([
            Post::class
        ]);
    }

    public function testEntityManager(): void
    {
//        $kernel = self::bootKernel();

        $this->assertSame('test', self::$kernel->getEnvironment());
//        $entitymanager = static::getContainer()->get('doctrine.orm.entity_manager');
        $this->assertInstanceOf(EntityManagerInterface::class, $this->entitymanager);
        //$myCustomService = self::$container->get(CustomService::class);

        $factory = static::getContainer()->get(PostFactory::class);
        $this->assertInstanceOf(PostFactory::class, $factory);

        $post1 = $factory->create('Post title 01', 'Post Body 01');
        $post2 = $factory->create('Post title 02', 'Post Body 02', null, 'published');
        $post3 = $factory->create('Post title 03', 'Post Body 03');
        $post4 = $factory->create('Post title 04', 'Post Body 04');
        $this->entitymanager->persist($post1);
        $this->entitymanager->persist($post2);
        $this->entitymanager->persist($post3);
        $this->entitymanager->persist($post4);

        $this->entitymanager->flush();

        $postRepo = static::getContainer()->get(PostRepository::class);

        $this->assertInstanceOf(PostRepository::class, $postRepo);

        $posts = $postRepo->findAll();
        $this->assertCount(4, $posts);
    }

//    public function testEntityManagerQuery():void
//    {
////        $kernel = self::bootKernel();
//
//        $postRepo = static::getContainer()->get(PostRepository::class);
//
//        $this->assertInstanceOf(PostRepository::class, $postRepo);
//
//        $posts = $postRepo->findAll();
//        $this->assertCount(4, $posts);
//    }

    private function truncateEntities(array $entities)
    {
        $connection = $this->entitymanager->getConnection();
        $databasePlatform = $connection->getDatabasePlatform();
        if ($databasePlatform->supportsForeignKeyConstraints()) {
            $connection->executeQuery('SET FOREIGN_KEY_CHECKS=0');
        }
        foreach ($entities as $entity) {
            $query = $databasePlatform->getTruncateTableSQL(
                $this->entitymanager->getClassMetadata($entity)->getTableName()
            );
            $connection->executeQuery($query);
        }
        if ($databasePlatform->supportsForeignKeyConstraints()) {
            $connection->executeQuery('SET FOREIGN_KEY_CHECKS=1');
        }
    }
}

truncateEntities()这个方法中,orm框架会根据不同的数据库创建不同的清空数据库表的SQL语句,然后执行SQL语句来清空数据库,我们在setUp()方法中直接调用清空数据库的方法,这里我们需要清空的是post数据库表,phpunit中的每个测试方法都是独立的,在testEntityManager()方法运行之前,它会启动内核,清空数据库 然后再插入数据。

testEntityManagerQuery()方法执行之前,它也会执行setUp()方法,这时数据库它是没有内容的,所以测试代码还会失败。我们把testEntityManagerQuery()方法中的代码粘贴到上个方法中,然后注释掉testEntityManagerQuery()方法,所有的测试代码都在testEntityManager()方法中。在testEntityManager()方法执行之前,它会启动内核,清空数据库,然后获取EntityManager对象,再执行插入方法,插入方法执行完之后,读取数据库,然后验证数据库。

我们再次执行测试代码,测试代码出错了,在清空数据库之前,首先要获取到EntityManager对象,我们调整一下代码,再次执行测试代码。这次测试就通过了,我们再次执行,测试仍然通过。

我们已经使用了findAll()方法,在下一节课,我们将测试PostRepository提供另外三个方法。

课程讨论

当前内容评论功能已关闭。