首页 > 解决方案 > 使用数据库访问在 Symfony 4 中测试服务的正确方法

问题描述

在 Symfony 4 中测试服务的正确方法是什么,它也访问数据库?

我是 Symfony4 的新手(在我为 Symfony2 开发之前),我想为服务编写我的第一个测试。

该服务是通过数据库中的实体/教义/ ORM 编写的,我要测试的每个方法都是触发数据库保存。

在 Symfony 2 中,当我使用 KernelTestCase 而不是 PHPUnit_Framework_TestCase 时就是这种情况,因为模拟 EntityManager 很麻烦,而且我经常还想检查测试数据库中的结果。

Symfony 4 的所有示例都只提到了用于测试命令的 KernelTestCase。

我的课:

class UserPropertyService implements UserPropertyServiceInterface
{


    public function __construct(EntityManager $em, LoggerInterface $logger)
    {
    ....
    }

....
}

我的测试尝试:

class UserPropertyServiceTest extends KernelTestCase
{
    /** @var UserPropertyService */
    private $userPropertyService;

    public function setUp()
    {
        self::bootKernel();
        $client = static::createClient();
        $container = $client->getContainer();

        $this->userPropertyService = self::$container->get('app.user_management.user_property_service');
}

结果是:

Cannot autowire service "App\Service\UserManagement\UserPropertyService": argument 
"$em" of method "__construct()" references class "Doctrine\ORM\EntityManager" 
but no such service exists. 
Try changing the  type-hint to one of its parents: interface "Doctrine\ORM\EntityManagerInterface", 
or interface "Doctrine\Common\Persistence\ObjectManager".

这里的正确方法是什么?我应该使用哪个测试类?

标签: unit-testingsymfonysymfony4

解决方案


这看起来像一个服务测试(不要通过客户端获取您的容器,这些容器是不同的)

顺便说一句,static::createClient();如果您扩展自KernelTestCase(对控制器测试和WebTestCase类的误解?)

<?php

namespace App\Tests\Service;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class UserPropertyServiceTest extends KernelTestCase
{
    /** @var UserPropertyService */
    private $myService;

    public function setUp() {
        self::bootKernel();
        $this->myService = self::$kernel->getContainer()->get('app.user_management.user_property_service');
    }

}

推荐阅读