Symfony 2.8:在测试控制器中注入模拟的存储库

时间:2017-05-15 09:15:50

标签: symfony phpunit symfony-2.8

我尝试为自定义控制器创建测试。在这一个中,这就是执行的内容:

代码

$users = $this->getDoctrine()
                ->getRepository('MyBundle:User')
                ->findAllOrderedByName();

在测试控制器中,这就是我正在做的事情:

$entityManager = $this
            ->getMockBuilder('Doctrine\ORM\EntityManager')
            ->setMethods(['getRepository', 'clear'])
            ->disableOriginalConstructor()
            ->getMock();

        $entityManager
            ->expects($this->once())
            ->method('getRepository')
            ->with('MyBundle:User')
            ->will($this->returnValue($userRepositoryMock));


        // Set the client
        $client = static::createClient();
        $client->getContainer()->set('doctrine.orm.default_entity_manager', $entityManager);

问题

但最后测试失败了,因为我的模拟似乎没有被使用:

  

测试\ MyBundle \控制器\ ListingControllerTest :: testAllAction   方法名称的期望失败等于string:getRepository   当被调用1次时。   预计方法被调用1次,实际上被称为0次。

有什么想法吗?

修改

在对评论发表评论后,我创建了一项服务:

services:
    my.user.repository:
        class:   MyBundle\Entity\UserRepository
        factory: ['@doctrine.orm.default_entity_manager', getRepository]
        arguments:
          - MyBundle\Entity\User

所以现在,我“只是”必须嘲笑回购:

$userRepositoryMock = $this->getMockBuilder('MyBundle\Entity\UserRepository')
            ->disableOriginalConstructor()
            ->setMethods(['findAllOrderedByName'])
            ->getMock();

        $userRepositoryMock
            ->expects($this->once())
            ->method('findAllOrderedByName')
            ->will($this->returnValue($arrayOfUsers));

并将其注入容器中:

$client->getContainer()->set('my.user.repository', $userRepositoryMock);

但我仍有同样的问题

1 个答案:

答案 0 :(得分:2)

不要在测试类中注入容器/实体管理器,而是注入doctrine存储库directly。另外,不要在测试中创建内核,测试应该快速运行。

更新1: 测试服务应该在构造函数中需要存储库。所以在你的测试中你可以用mock替换它。 $client = static::createClient()用于使用fixture(功能测试)针对真实数据库测试控制器。不要将它用于测试具有模拟依赖关系的服务(单元测试)。

更新2:单元测试示例:

class UserServiceTest extends UnitTestCase
{
    public function test_that_findAllWrapper_calls_findAllOrderedByName()
    {

        //GIVEN
        $arrayOfUsers = [$user1, $user2];

        $userRepo = $this->getMockBuilder('AppBundle\Repository\UserRepository')
            ->disableOriginalConstructor()
            ->getMock();
        $userRepo
            ->expects($this->once())
            ->method('findAllOrderedByName')->willReturn($arrayOfUsers);


        $userService = new UserService($userRepo);

        //WHEN
        $result = $userService->findAllWrapper();

        //THEN
        $this->assertEquals($arrayOfUsers, $result);
    }
}

class UserService {
    private $userRepo;

    public function __construct(UserRepository $repo)
    {
        $this->userRepo = $repo;
    }

    public function findAllWrapper()
    {
        return $this->userRepo->findAllOrderedByName();
    }
}