【问题标题】:How to mock 'find' method in Symfony 3如何在 Symfony 3 中模拟“查找”方法
【发布时间】:2017-04-25 15:02:14
【问题描述】:

我正在尝试模拟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(); 
}

这是我们调用find函数的方法

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 类已被模拟,但它没有模拟实体管理器和存储库。

谢谢

【问题讨论】:

  • 使用 Mockery 非常简单 docs.mockery.io/en/latest 尝试一下 $repo->shouldReceive('find')->once()->andReturn([1,2,3]); 之类的东西
  • 谢谢,这个很有用!!

标签: php symfony testing doctrine-orm mocking


【解决方案1】:

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

// 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 是通过构造函数注入到类中的,因此很容易在测试中传递模拟对象:

// 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));
    }
}

在此示例中,您从内到外构建模拟,首先创建由存储库返回的员工,该存储库本身由实体管理器返回。这样,测试中就不会涉及到真正的类。

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

【讨论】:

    猜你喜欢
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    相关资源
    最近更新 更多