yaboroda / ybsy-test-helper-bundle
This bundle provide tool for easing unit tests with test db
This package's canonical repository appears to be gone and the package has been frozen as a result.
Requires
- php: >=5.6
- doctrine/doctrine-bundle: ~1.4
- doctrine/doctrine-fixtures-bundle: ^2.
- doctrine/orm: ^2.4.8
- phpunit/phpunit: ^5.7
- symfony/symfony: 2.8.*
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);