PhpUnit тесты - подводные камни

Оказывается, PhpUnit в каждом тесте использует копии переменных объявленных в методе setUp.

По этой причине, используя Doctrine, когда я писал тест на UPDATE записи в таблице базы данных, у меня получался INSERT. 

Привожу пример неправильного когда, когда ожидается UPDATE, а получается INSERT.

<?php
namespace Yapro\OrientDB\Tests;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;// необходим для метода setUp()

class Crud extends WebTestCase
{
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $_em;

    /**
     * емэйл которым будем проверять добавление/обновление/удаление (как некое уникальное значение сущности)
     * @var string
     */
    private $email = 'test@site.ru';

    /**
     * настройки теста
     */
    protected function setUp()
    {
        $kernel = static::createKernel();
        $kernel->boot();
        $this->_em = $kernel->getContainer()->get('doctrine.orm.entity_manager');
        $this->_em->beginTransaction();
    }

    function testFind()
    {
        // получаем репозиторий
        $repository = $this->_em->getRepository('AcmeDemoBundle:UnitTestEntity');

        return $repository;
    }

    /**
     * @depends testFind
     */
    function testUpdate($repository)
    {
        // проверяем сущестование записи
        $entity = $repository->findOneBy(array('email'=>$this->email));
 
        // обновляем строку в таблице
        $entity->setTimeCreated(2);
        $this->_em->persist($entity);
        $this->_em->flush();
    }
}

Обратите внимание на $this->_em, которая в каждом из методов является копией основной (объявленной в методе setUp).

А теперь пример правильного когда, когда выполняется ожидаемый UPDATE.

<?php
namespace Yapro\OrientDB\Tests;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;// необходим для метода setUp()

class Crud extends WebTestCase
{
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $_em;

    /**
     * емэйл которым будем проверять добавление/обновление/удаление (как некое уникальное значение сущности)
     * @var string
     */
    private $email = 'test@site.ru';

    /**
     * настройки теста
     */
    protected function setUp()
    {
        $kernel = static::createKernel();
        $kernel->boot();
        $this->_em = $kernel->getContainer()->get('doctrine.orm.entity_manager');
        $this->_em->beginTransaction();
    }

    function testUpdate()
    {
        // получаем репозиторий
        $repository = $this->_em->getRepository('AcmeDemoBundle:UnitTestEntity');

        // проверяем сущестование записи
        $entity = $repository->findOneBy(array('email'=>$this->email));
 
        // обновляем строку в таблице
        $entity->setTimeCreated(2);
        $this->_em->persist($entity);
        $this->_em->flush();
    }
}

При этом $this->_em, в методе testUpdate это уже копия из метода setUp. А если например изменить значение переменной $this->_em, то в следующем тестовом методе обратившись к $this->_em мы получим копию первоначального значения из метода setUp. 

Пример сократил для понимания дела.

Как замокать приватный метод

К сожалению, PHP не позволяет менять доступ метода, поэтому у Вас 2 выхода:

1. использовать AspectMock

2. заменить private на protected

$mock = $this->getMockBuilder(MyClass::class)->disableOriginalConstructor()->setMethods(array('myProtectedMethod'))->getMock();
$mock->method('myProtectedMethod')->willReturn(123);
$response = $mock->myPublicFunction();

Как проверить значения аргументов, которые будут отправлены в mockFunction при тестировании метода saveMe

$expectedArguments = [1,2,3];

$this->someMock->expects($this->any())->method('mockFunction')->with($expectedArguments);

$this->realObject->saveMe();

Удачки в тестировании.

Оцени публикацию:
  • 0,0
Оценили человек: 0
Теги : PhpUnit, UnitTest

Похожие статьи:

Справочники и учебники:


Предложения и пожелания:
Ваше имя:
Ваш E-mail:
Сколько будет Οдин + Τри
Главная
X

youtube.com/watch?v=7hFivbgIEqk

При полном или частичном использовании материалов данного сайта, ссылка на сайт "yapro.ru" обязательна как на источник информации.
Автоматический импорт материалов и информации с сайта запрещен.
Copyrights © 2007 - 2017 YaPro.Ru

Главная » Веб-мастеру » PHP »