php - 如何在 Symfony 3 中模拟 'find' 方法

标签 php symfony testing doctrine-orm mocking

我正在尝试模拟 EntityRepositoryfind 方法,这样测试就不会在数据库中查找数据,但它似乎并没有上类。这是测试类的setUp方法

public function setUp()
{
    parent::setUp();

    $this->client = static::createClient();
    $this->peopleManager = $this->getMockBuilder(PeopleManager::class)
        ->setMethods(['createPerson','peopleUpdate', 'peopleDelete', 'peopleRead'])
        ->disableOriginalConstructor()
        ->getMock();

   $this->repository = $this->getMockBuilder(EntityRepository::class)
       ->disableOriginalConstructor()
       ->getMock();

   $this->em = $this->getMockBuilder(EntityManager::class)
       ->disableOriginalConstructor()
       ->getMock(); 
}

这是我们调用查找函数的方法

public function updatePersonAction($id, Request $request)
{
    $repository = $this->getDoctrine()->getRepository('GeneralBundle:People');
    $person= $repository->find($id);
    if($person)
    {
        $data = $request->request->get('array');
        $createdPeople = array();
        $UpdatedPerson = "";
        foreach($data as $content)
        {
            $prueba = $this->get('people.manager');
            $UpdatedPerson = $prueba->peopleUpdate(
                $person,
                $content['name'],
                $content['surname'],
                $content['secondSurname'],
                $content['nationality'],
                $content['birthday'],
                $content['identityCard'],
                $content['identityCardType']
            );
            array_push($createdPeople, $person);
        }
        $serializedEntity = $this->get('serializer')->serialize($UpdatedPerson, 'json');
        return new Response($serializedEntity);
    } else {
        $serializedEntity = $this->get('serializer')->serialize('Doesn\'t exists any person with this id', 'json');
        return new Response($serializedEntity);
    }
}

调试器显示 peoplemanager 类被模拟,但它没有模拟实体管理器和存储库。

谢谢 <3.

最佳答案

假设您要测试的类如下所示:

// src/AppBundle/Salary/SalaryCalculator.php
namespace AppBundle\Salary;

use Doctrine\Common\Persistence\ObjectManager;

class SalaryCalculator
{
    private $entityManager;

    public function __construct(ObjectManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function calculateTotalSalary($id)
    {
        $employeeRepository = $this->entityManager
            ->getRepository('AppBundle:Employee');
        $employee = $employeeRepository->find($id);

        return $employee->getSalary() + $employee->getBonus();
    }
}

由于 ObjectManager 通过构造函数注入(inject)到类中,因此很容易在测试中传递模拟对象:

// tests/AppBundle/Salary/SalaryCalculatorTest.php
namespace Tests\AppBundle\Salary;

use AppBundle\Entity\Employee;
use AppBundle\Salary\SalaryCalculator;
use Doctrine\ORM\EntityRepository;
use Doctrine\Common\Persistence\ObjectManager;
use PHPUnit\Framework\TestCase;

class SalaryCalculatorTest extends TestCase
{
    public function testCalculateTotalSalary()
    {
        // First, mock the object to be used in the test
        $employee = $this->createMock(Employee::class);
        $employee->expects($this->once())
            ->method('getSalary')
            ->will($this->returnValue(1000));
        $employee->expects($this->once())
            ->method('getBonus')
            ->will($this->returnValue(1100));

        // Now, mock the repository so it returns the mock of the employee
        $employeeRepository = $this
            ->getMockBuilder(EntityRepository::class)
            ->disableOriginalConstructor()
            ->getMock();
        $employeeRepository->expects($this->once())
            ->method('find')
            ->will($this->returnValue($employee));

        // Last, mock the EntityManager to return the mock of the repository
        $entityManager = $this
            ->getMockBuilder(ObjectManager::class)
            ->disableOriginalConstructor()
            ->getMock();
        $entityManager->expects($this->once())
            ->method('getRepository')
            ->will($this->returnValue($employeeRepository));

        $salaryCalculator = new SalaryCalculator($entityManager);
        $this->assertEquals(2100, $salaryCalculator->calculateTotalSalary(1));
    }
}

在此示例中,您正在从内到外构建模拟,首先创建由 Repository 返回的员工,而 Repository 本身由 EntityManager 返回。这样,测试就不会涉及真正的类。

来源: http://symfony.com/doc/current/testing/database.html

关于php - 如何在 Symfony 3 中模拟 'find' 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43614374/

相关文章:

php - 如何使用多个 SUM() 创建 mySQL 语句?

php - 在网站上调整图像大小以提高效率。

php - Symfony2模板不支持 "bundle"参数

php - Symfony4:Doctrine2 有效但在 PHPUnit 测试中没有连接(内核启动)

c++ - 随机数据测试

testing - 软件开发工具——从用户目标到测试

php - 将动态数据从 div 传递到同一页面上的另一个 div

symfony - 如何在生产环境中从 symfony2 profiler 获取学说查询计数?

reactjs - 使用 jest-each 进行动态数据测试

PHP、mysqli 和表锁?