如何编写存储库测试而不在数据库上执行查询

时间:2018-12-06 14:22:49

标签: doctrine-orm doctrine phpunit symfony4

我花费了很多时间试图为存储库功能创建适当的Phpunit测试,但仍然没有成功,所以这就是为什么我向你们求助

我试图编写一个测试,测试我的存储库功能,而未连接到数据库

我具有此存储库功能(Symfony 4)

class RequestRepository extends EntityRepository
{
   public function getCompletedRequestByName($name)
        {
            $requestsStatuses = $this->createQueryBuilder('r')
                ->join('r.domains', 'd', Join::WITH, 'r.id = d.request')
                ->where('r.name = :name')
                ->andWhere('r.status = :completed')
                ->setParameter('name', $name)
                ->setParameter('completed', 'COMPLETED')
                ->getQuery()
                ->getOneOrNullResult();
            return $requestsStatuses;
        }
}

这是我的考验

public function testGetCompletedRequestByName()
{
    $entityM =
        $this->getMockBuilder(EntityManagerInterface::class)
            ->disableOriginalConstructor()
            ->getMockForAbstractClass();

    $classMetaData =
        $this->getMockBuilder(ClassMetadata::class)
            ->disableOriginalConstructor()
            ->getMockForAbstractClass();

    $repo = new RequestRepository($entityM, $classMetaData);
    var_dump($repo->getCompletedRequestByName('antrax.com'));
    die();
}

我得到的错误是

1) App\Repository\RequestRepositoryTest::testGetCompletedRequestByName
Error: Call to a member function select() on null

有人可以帮助我,如何编写测试,测试我的存储库功能,而无需连接数据库和执行任何查询。如果您需要任何其他信息,请告诉我,我会提供!谢谢!

1 个答案:

答案 0 :(得分:0)

我为我的案件找到了解决方案。如果有任何需要,这就是我的测试样子

public function testGetCompletedRequestByName()
{

    $queryBuilder = $this->getMockBuilder(QueryBuilder::class)->disableOriginalConstructor()
        ->setMethods(['setParameter', 'getQuery', 'getOneOrNullResult', 'join', 'andWhere', 'where'])->getMock();

    $queryBuilder->method('getQuery')->willReturnSelf();

    $queryBuilder->method('setParameter')->willReturnCallback(function ($field, $value) use ($queryBuilder){
        if ($field == 'name') {
            $this->assertSame('antrax.com', $value);
        } elseif ($field == 'completed') {
            $this->assertSame('COMPLETED', $value);
        }
        return $queryBuilder;
    });

    $queryBuilder->method('join')->willReturnCallback(function ($field, $alias, $operator, $cond) use ($queryBuilder){

        $this->assertSame('r.domains', $field);
        $this->assertSame('d', $alias);
        $this->assertSame(Join::WITH, $operator);
        $this->assertSame('r.id = d.request', $cond);

        return $queryBuilder;
    });

    $queryBuilder->method('where')->willReturnCallback(function ($cond) use ($queryBuilder){

        $this->assertSame('r.name = :name', $cond);
        return $queryBuilder;
    });

    $queryBuilder->method('andWhere')->willReturnCallback(function ($cond) use ($queryBuilder){

        $this->assertSame('r.status = :completed', $cond);
        return $queryBuilder;
    });

    $repositoryMock =
        $this->getMockBuilder(RequestRepository::class)->disableOriginalConstructor()
            ->setMethods(['createQueryBuilder'])->getMock();

    $repositoryMock->method('createQueryBuilder')->willReturnCallback(function ($alias) use ($queryBuilder){
        $this->assertSame('r', $alias);
        return $queryBuilder;
    });

    $repositoryMock->getCompletedRequestByName('antrax.com');
}