单元测试中的Symfony Custom Repository类

时间:2018-06-16 13:32:05

标签: unit-testing symfony doctrine phpunit

我正在尝试创建一个单元测试来测试与数据库交互的Symfony 4代码。

需要测试的方法包含对自定义存储库类的调用,这在运行phpunit时导致错误:错误:调用未定义的方法Mock_ObjectRepository_583b1688 :: findLastRegisteredUsers()

我怀疑问题可能与我如何调用存储库有关,但不确定如何解决它。

测试/ UserTest.php

game_name = html_soup.find_all("div", class_="product_item product_title")[1].text.strip()

存储库/ UserRepository.php

Pillars of Eternity II: Deadfire

的src /用户/ UserCalculator.php

class UserTest extends TestCase
{
    public function testCalculateTotalUsersReturnsInteger()
    {

        $user = new User();
        $user->setFullname('Test');

        // ! This might be what is causing the problem !
        $userRepository = $this->createMock(ObjectRepository::class); 

        $userRepository->expects($this->any())
            ->method('find')
            ->willReturn($user);

        $objectManager = $this->createMock(ObjectManager::class);

        $objectManager->expects($this->any())
            ->method('getRepository')
            ->willReturn($userRepository);

        $userCalculator = new RegistrationHandler($objectManager);
        $result = $registrationHandler->getAccountManager();

        $this->assertInternalType('int', $result);
    }
}

为了清楚起见,使用以下注释在User Entity类中指定了自定义EntityRepository类的路径

class UserRepository extends EntityRepository
{

    public function findLastRegisteredUsers($maxResults)
    {
        return $this->createQueryBuilder('user')
            ->andWhere('user.customField IS NOT NULL')
            ->addOrderBy('user.id', 'DESC')
            ->setFirstResult(0)
            ->setMaxResults($maxResults)
            ->getQuery()
            ->execute();
    }
}

如何让Test使用自定义存储库类? 我想我可能需要在$ userRepository = $ this-> createMock(ObjectRepository :: class); 例如使用$ this-> getMockBuilder()?

1 个答案:

答案 0 :(得分:2)

您可以为此目的使用集成测试:

此类扩展 KernelTestCase

class UserTest extends KernelTestCase
{
    public function testCalculateTotalUsersReturnsInteger()
    {

        self::bootKernel();
        $userCalculator = self::$kernel->getContainer()
        ->get('test.'.UserCalculator::class);


        $result = $userCalculator->calculateTotalUsers();

        $this->assertInternalType('int', $result);
    }
}

services_test.yml 中,您需要注册此服务:

test.App\User\UserCalculator: '@App\User\UserCalculator'

你可以打电话给你的方法:

 $result = $userCalculator->calculateTotalUsers();
 $this->assertInternalType('int', $result);

并使用Assert进行测试。

有关集成测试的文档,我从那里得到了这个例子: https://knpuniversity.com/screencast/phpunit/integration-tests

<强>更新 如果您想使用UniTest进行完全隔离测试并遇到错误:尝试配置无法配置的方法...

您需要在第一个模拟

中直接模拟您的存储库
$userReppsitory = $this->createMock(UserRepository::class)

并且你需要改变方法(&#39;找到&#39;)到method('findLastRegisteredUsers')

使用UnitTest更新

use PHPUnit\Framework\TestCase;
use Doctrine\Common\Persistence\ObjectManager;
use App\User\UserCalculator;
class UserTest extends TestCase
{
     public function testCalculateTotalUsersReturnsInteger()
        {

            $employee = new User();
            $employee->setFullname('test');

            // Now, mock the repository so it returns the mock of the employee
            $employeeRepository = $this->createMock(\App\Repository\UserRepository::class);

            $employeeRepository->expects($this->any())
                ->method('findLastRegisteredUsers')
                ->willReturn($employee);
            // Last, mock the EntityManager to return the mock of the repository
            $objectManager = $this->createMock(ObjectManager::class);

            $objectManager->expects($this->any())
                ->method('getRepository')
                ->willReturn($employeeRepository);

            $userCalculator = new UserCalculator($objectManager);

            $result = $userCalculator->calculateTotalUsers();
        } 
}