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

Новые заметки:

Про что мы забываем когда делаем оценку задачи по времени

Список вопросов для собеседования разработчика по телефону

Symfony2 авторизация без Doctrine2 для чайника

Phpstorm7 LiveEdit

Жесткий хабр или не хабр, тогда кто?

Яндекс.Деньги мошенничество

Как узнать какие страницы в поиске яндекса или это секрет

Последние комменты:

Yapro CMS:

Здравствуйте, Гость | Войти | Регистрация | Карта сайта | RSS ленты | Ошибка в тексте? Выделите её мышкой и нажмите: Ctrl + Enter

youtube.com/watch?v=7hFivbgIEqk

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

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