yaboroda/ybsy-test-helper-bundle

This bundle provide tool for easing unit tests with test db

1.1.1 2018-06-08 07:03 UTC

This package is auto-updated.

Last update: 2020-08-08 13:27:01 UTC


README

Этот бандл для symfony 2.8 поможет настроить модульное тестирование с тестовой базой данных на sqlite.
Поскольку используется sqlite, которая хранит БД в файле, настройка дополнительной БД на сервере не требуется.
Перед первым тестом каждого класса БД создается с нуля из фикстур и после этого файл с данными копируется во временный файл. Перед каждым тестом БД не заливается из фикстур, а восстанавливается из временного файла. Это экономит значительное количество времени при выполнении тестов.

Требования

  • php 5.6
  • расширение php pdo_mysql
  • symfony 2.8
  • phpunit 5.7
  • doctrine 1.4
  • doctrine-fixtures-bundle 2.*

Установка

$ composer require yaboroda/ybsy-test-helper-bundle

Настройка

в файл app/config_test.yml:

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_sqlite
                path:     %kernel.cache_dir%/test.db

Использование

наследуем свой класс теста от YaBoroda\TestHelperBundle\Tests\TestHelper

<?php 
namespace AppBundle\Tests\Service;

use YaBoroda\TestHelperBundle\Tests\TestHelper;
use AppBundle\Service\BaseService;

class BaseServiceTest extends TestHelper
{
    // Метод вызывается перед первым тестом класса
    public static function setUpBeforeClass()
    {
        self::$fixturesDir = 'src/AppBundle/DataFixtures/ORM/';
        self::prepareTestDatabase();
    }
    
    public static function testGettingService()
    {
        $baseService = $this->getContainer()->get('baseService');
        $this->assertInstanceOf(BaseService::class, $baseService);
    }
}

Если какое-то действие нужно выполнять перед каждым тестом, переопределите метод setUp(), но не забудьте вызвать родительский метод

    public function setUp()
    {
        parent::setUp();
        // дальше ваш код
    }

Если вам надо как-то модифицировать контейнер, то вы можете переопределить метод getContainer(); Этот же контейнер будет использоваться в методах getEntityManager() и getQueryBuilder()
После этого для получения немодифицированного контейнера используйте метод getRealContainer()


    protected function getContainer()
    {
        $container = $this->getRealContainer();

        // тут делайте с ним что хотите

        return $container;
    }

Использование фикстур

  • В self::$fixturesDir задаем папку с фикстурами относительно корня проекта
  • Метод self::prepareTestDatabase() создает схему БД и заливает в нее фикстуры, в качестве параметра передается имя файла фикстур или массив имен
  • При вызове без параметров, фикстуры будут искаться в файле DefaultFixture.php
  • Можно передать массив с именами файлов, тогда первый файл зальется в обычном порядке, а остальные в режиме append, таким образом в БД будет информация из всех переданных фикстур

Если вам не нужна база данных, вы можете отменить заливку фикстур и откат БД между тестами для экономии времени.

    public static function setUpBeforeClass()
    {
        ;
    }

    public function setUp()
    {
        // если сервис контейнер вам все-таки нужен, вызовите тут инициацию окружения
        $this->setUpApplication();
    }

Инструментарий

получение контейнера

$container = $this->getContainer();

получение EntityManager

$em = $this->getEntityManager();

получение QueryBuilder

$qb = $this->getQueryBuilder();

авторизовать пользователя (передайте NULL что бы получить авторизацию анонима)
второй параметр - имя фаервола из security.yml
по умолчанию 'secured_area', так что если у вас такой же, второй параметр можно не передавать

$this->authorizeUser($user, $firewall);

получить protected или private свойство объекта

$prop = $this->getProtectedProperty($object, $propertyName);

выполнить protected или private метод объекта

$result = $this->callProtectedMethod($object, $methodName, array($param1, $param2));

установить request scope для контейнера (необходимо для некоторых действий)

$this->setRequestScopeToContainer($container);

// если вторым параметром передать объект Request, то он добавится в стек реквестов
$this->setRequestScopeToContainer($container, $request);

// пустой Request можно получить тут же, модифицировать его и потом установить в контейнер
$request = $this->getEmptyRequest();

эти методы используются для управления файлом базы данных и в обычных обстоятельсятвах вам не нужно их вызывать непосредственно, но когда-то может пригодиться

// загрузить файл фикстур с очисткой БД
self::loadFixtures($fileName);

// добавить данные из фикстур к БД
self::appendFixtures($fileName);

// скопировать текущий файл БД во временный (если имя файла не передавать, то скопируется в test.db.bk)
self::backupDatabase($fileName);

// скопировать сохраненный ранее файл БД на место текущего (если имя файла не передавать, то скопируется из test.db.bk)
$this->restoreDatabase($fileName);