Фильтры фикстур
Фильтр фикстур — класс, имплементирующий \Doctrine\Fixture\Filter\Filter. Определяет условия того, какие фикстуры должны быть выполнены.
Для работы с фильтрами фикстур используется специальный менеджер плагинов — \Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface. Пример получения фильтров фикстур в фабрике:
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface;
use Doctrine\Fixture\Filter\GroupedFilter;
class ExampleFactory implements FactoryInterface
{
/**
* @inheritDoc
*
* @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
/** @var FixtureFilterManagerInterface $fixtureFilterManager */
$fixtureFilterManager = $serviceLocator->get(FixtureFilterManagerInterface::class);
$fixtureFilter = $fixtureFilterManager->get(GroupedFilter::class);
}
}
Поддерживаются следующие фильтры:
Фильтр | Описание |
---|---|
\Doctrine\Fixture\Filter\ChainFilter | Позволяет объединить фильтры в цепочку |
\Doctrine\Fixture\Filter\GroupedFilter | Позволяет запускать фикстуры, принадлежащие к определенной группе |
\Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture | Обеспечивает возможность не выполнять фикстуры повторно |
Каждый из этих фильтров фикстур зарегистрирован в менеджере плагинов \Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface.
Фильтр \Doctrine\Fixture\Filter\ChainFilter
Объеденяет фильтры в цепочку.
Пример использования:
$testFixture = new \Nnx\DoctrineFixtureModule\PhpUnit\TestData\FixtureTestApp\TestModule1\FooFixture();
/** @var \Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface $fixtureFilterManager */
$fixtureFilterManager = $serviceLocator->get(\Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface::class);
$options = [
'filterList' => [
$fixtureFilterManager->get(\Doctrine\Fixture\Filter\GroupedFilter::class, [
'allowedGroupList' => [
'group1'
]
]),
$fixtureFilterManager->get(\Doctrine\Fixture\Filter\GroupedFilter::class, [
'allowedGroupList' => [
'group2'
]
]),
]
];
if ($fixtureFilterManager->get(\Doctrine\Fixture\Filter\ChainFilter::class, $options)->accept($testFixture)) {
$testFixture->import();
}
При создании экземпляра фильтра фикстур \Doctrine\Fixture\Filter\ChainFilter через плагин-менеджер в опциях с помощью параметра filterList можно указать массив объектов фильтров фикстур.
После вызова метода accept у экземпляра объекта \Doctrine\Fixture\Filter\ChainFilter у всех фильтров фикстур, образующих цепочку, будет вызван аналогичный метод и произведена проверка, нужно ли выполнять данную фикстуру.
Фильтр \Doctrine\Fixture\Filter\GroupedFilter
Для работы с группами фикстур необходимо, чтобы фикстуры реализовывали интерфейс \Doctrine\Fixture\Filter\GroupdFixteure. Метод getGroupList должен возвращать массив с именами групп, к которым относится фикстура.
Пример фикстуры:
namespace Doctrine\Test\Mock\Grouped;
use Doctrine\Fixture\Filter\GroupedFixture;
class FixtureA implements GroupedFixture
{
/**
* {@inheritdoc}
*/
public function getGroupList()
{
return array('test', 'another_test');
}
/**
* {@inheritdoc}
*/
public function import()
{
}
/**
* {@inheritdoc}
*/
public function purge()
{
}
}
При создании экземпляра фильтра фикстур \Doctrine\Fixture\Filter\GroupedFilter через плагин-менеджер в опциях с помощью параметра allowedGroupList можно указать список групп, к которым должна относится фикстура, чтобы она была выполнена.
Также можно указать параметр onlyImplementors (значение по умолчанию — false). Если этот параметр имеет значение true, то все фикстуры, которые не реализуют интерфейс \Doctrine\Fixture\Filter\GroupdFixteure, не будут выполнены.
$testFixture = new \Doctrine\Test\Mock\Grouped\FixtureA();
/** @var \Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface $fixtureFilterManager */
$fixtureFilterManager = $serviceLocator->get(\Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface::class);
$options = [
'allowedGroupList' => [
'another_test'
],
'onlyImplementors' => false
];
if ($fixtureFilterManager->get(\Doctrine\Fixture\Filter\GroupedFilter::class, $options)->accept($testFixture)) {
$testFixture->import();
}
Фильтр \Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture
Фильтр позволяет для конкретного Executor'a (описанного в конфигах приложения) выполнить фикстуры только один раз. Таким образом, повторный запуск такого Executor'a не приведет к повторному выполнению ранее выполненных фикстур, будут выполнены только новые фикстуры.
Быстрый старт при использование \Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture
Необходимо зарегистрировать сущность для работы с \Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture. В случае если для работы с Doctrine2 используется doctrine/doctrine-orm-module, необходимо в цепочку драйверов, которую использует ObjectManager Doctrine2, добавить драйвер для сущностей модуля nnx/doctrine-fixture-module.
return [
'doctrine' => [
'entitymanager' => [
'orm_default' => [
'configuration' => 'orm_default',
'connection' => 'orm_default',
]
],
'connection' => [
'orm_default' => [
'configuration' => 'orm_default',
]
],
'configuration' => [
'orm_default' => [
'driver' => 'orm_default'
]
],
'driver' => [
'orm_default' => [
'class' => 'Doctrine\ORM\Mapping\Driver\DriverChain',
'drivers' => [
'Nnx\\DoctrineFixtureModule\\Entity' => 'Nnx\\DoctrineFixtureModule'
]
]
]
],
];
Независимое использование фильтра \Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture
Для использования фильтра FilterUsedFixture при его создании необходимо передать Executor, в контексте которого будет запускаться фикстура.
//Создаем компонент, отвечающий за запуск фикстур
//Указываем через опции его имя
/** @var \Nnx\DoctrineFixtureModule\Executor\FixtureExecutorManagerInterface $fixtureExecutorManager */
$fixtureExecutorManager = $serviceLocator->get(\Nnx\DoctrineFixtureModule\Executor\FixtureExecutorManagerInterface::class);
/** @var \Nnx\DoctrineFixtureModule\Executor\Executor $executor */
$executor = $fixtureExecutorManager->get(\Nnx\DoctrineFixtureModule\Executor\Executor::class, [
'name' => 'myFixtureExecutor'
]);
//Создаем загрузчик фикстур
//Загрузчик знает, как загрузить одну тестовую фикстуру
/** @var \Nnx\DoctrineFixtureModule\Loader\FixtureLoaderManagerInterface $loaderManager */
$loaderManager = $serviceLocator->get(\Nnx\DoctrineFixtureModule\Loader\FixtureLoaderManagerInterface::class);
$options = [
'classList' => [
\Nnx\DoctrineFixtureModule\PhpUnit\TestData\FixtureTestApp\TestModule1\FooFixture::class
]
];
/** @var \Doctrine\Fixture\Loader\ClassLoader::class $loader */
$loader = $loaderManager->get(\Doctrine\Fixture\Loader\ClassLoader::class, $options);
//Создаем фильтр. Указываем через параметры, для какого Executor'a фильтр используется
/** @var \Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface $fixtureFilterManager */
$fixtureFilterManager = $serviceLocator->get(\Nnx\DoctrineFixtureModule\Filter\FixtureFilterManagerInterface::class);
$options = [
'contextExecutor' => $executor
];
$filter = $fixtureFilterManager->get(\Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture::class, $options);
//Устанавливаем загрузчик и фильтр
$executor->setLoader($loader);
$executor->setFilter($filter);
$executor->import();
После того как будет запущен процесс загрузки (или удаления) данных из фикстуры, в специальной таблице (@see \Nnx\DoctrineFixtureModule\Entity\UsedFixture) будет сохранена информация, о том, что для Executor'a с заданным именем (имя параметра name, используемое в опциях при создание Executor'a), была выполнена фикстура \Nnx\DoctrineFixtureModule\PhpUnit\TestData\FixtureTestApp\TestModule1\FooFixture. При повторном запуске данная фикстура выполняться не будет.
Использование \Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture с помощью конфигурации в приложении
Для использования \Nnx\DoctrineFixtureModule\Filter\FilterUsedFixture с помощью конфигурации в приложении можно руководствоваться следующим примером:
Пример конфигурации:
return [
'nnx_doctrine_fixture_module' => [
'fixturesLoaders' => [
'testChainFixtureLoader' => [
[
'name' => ClassLoader::class,
'options' => [
'classList' => [
TestModule1\FooFixture::class,
TestModule1\BarFixture::class,
]
]
],
[
'name' => DirectoryLoader::class,
'options' => [
'directory' => __DIR__ . '/../../fixtures'
]
],
[
'name' => 'childTestChain',
]
],
],
'filters' => [
'testFilterUsedFixture' => [
[
'name' => FilterUsedFixture::class
]
]
],
'executors' => [
'testFilterUsedFixture' => [
'fixturesLoader' => 'testChainFixtureLoader',
'filter' => 'testFilterUsedFixture'
]
]
]
];
Пример использования:
/** @var FixtureExecutorManagerInterface $fixtureExecutorManager */
$fixtureExecutorManager = $serviceLocator()->get(FixtureExecutorManagerInterface::class);
$executor = $fixtureExecutorManager->get('testFilterUsedFixture');
$executor->import();
В результате фикстуры, описанные в fixturesLoaders (секция с именем testChainFixtureLoader), будут выполнены только один раз.
В базе данных в соответствующей таблице (@see \Nnx\DoctrineFixtureModule\Entity\UsedFixture) будет добавлена информация о том, какие фикстуры были выполнены для Executor'a с именем testFilterUsedFixture.