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



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

法典

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

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

$entityManager = $this
            ->getMockBuilder('DoctrineORMEntityManager')
            ->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);

问题

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

tests\MyBundle\Controller\ListingControllerTest::testAllAction 方法名称等于字符串:getRepository 的预期失败 调用 1 次时。 方法预计调用 1 次,实际调用 0 次。

知道吗?

编辑

在评论之后,我创建了一个服务:

services:
    my.user.repository:
        class:   MyBundleEntityUserRepository
        factory: ['@doctrine.orm.default_entity_manager', getRepository]
        arguments:
          - MyBundleEntityUser

所以现在,我"只是"不得不嘲笑回购:

$userRepositoryMock = $this->getMockBuilder('MyBundleEntityUserRepository')
            ->disableOriginalConstructor()
            ->setMethods(['findAllOrderedByName'])
            ->getMock();
        $userRepositoryMock
            ->expects($this->once())
            ->method('findAllOrderedByName')
            ->will($this->returnValue($arrayOfUsers));

并将其注入容器中:

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

但我仍然有同样的问题

不要在测试类中注入容器/实体管理器,而是直接注入原则存储库。另外,不要在测试中创建内核,测试应该运行得很快。

更新 1:测试服务应该需要构造函数中的存储库。因此,在您的测试中,您可以将其替换为模拟。 $client = static::createClient()用于针对带有夹具的真实数据库测试控制器(功能测试(。不要将其用于测试具有模拟依赖项的服务(单元测试(。

更新 2:单元测试示例:

class UserServiceTest extends UnitTestCase
{
    public function test_that_findAllWrapper_calls_findAllOrderedByName()
    {
        //GIVEN
        $arrayOfUsers = [$user1, $user2];
        $userRepo = $this->getMockBuilder('AppBundleRepositoryUserRepository')
            ->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();
    }
}

最新更新