В нашем приложении мы устанавливаем объекты в статические свойства этих светильников, поэтому их можно легко использовать из тестов.
class CategoryTestFixture
extends \Doctrine\Common\DataFixtures\AbstractFixture
implements
\Doctrine\Common\DataFixtures\OrderedFixtureInterface,
\Symfony\Component\DependencyInjection\ContainerAwareInterface
{
/** @var \My\Category */
public static $fooCategory;
/** @var \My\Category */
public static $barCategory;
/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
private $container;
public function load(ObjectManager $manager)
{
self::$fooCategory = new Category('Foo');
$entityManager->persist(self::$fooCategory);
self::$barCategory = new Category('Bar');
$entityManager->persist(self::$barCategory);
$entityManager->flush();
}
// you can inject the container,
// so you can use your Facades in fixtures
public function getContainer(): ContainerInterface
{
return $this->container;
}
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}
Есть несколько важных правил для этого:
- Убедитесь, что вы не вызываете
$em->clear()
в ваших светильниках, так что вы можете напрямую использовать объекты в других классах светильников.
- Звоните
$em->clear()
после того, как светильники загружены, поэтому они не влияют на ваши тесты.
- Перед каждым тестом сделайте копию подготовленной базы данных и используйте эту копию для своих тестов, а не «базу данных шаблонов». Таким образом, вы можете безопасно модифицировать данные. Его можно дополнительно оптимизировать, но это наиболее простое решение.
- Не сливайте и не пытайтесь зарегистрировать как управляемые оригинальные светильники в своих тестах.
Теперь, когда вы создали светильники, можно использовать их как этот
$id = CategoryTestFixture::$barCategory->getId();
Кроме того, вы можете ссылаться на все их свойства, а не только идентификаторы. Поэтому, если вы скажете, что хотите утверждать, что ваш api вернул правильные категории, вы можете сделать это вот так.
$this->assertArraySubset([
[
'id' => CategoryTestFixture::$fooCategory->getId(),
'name' => CategoryTestFixture::$fooCategory->getName(),
],
[
'id' => CategoryTestFixture::$barCategory->getId(),
'name' => CategoryTestFixture::$barCategory->getName(),
]
], $apiResponseData);
и если вы хотите изменить данные только для одного TestCase, используйте свойство светильника, чтобы изменить базу данных, а затем ясно EM aftewards, так что вы не создаете побочные эффекты уже заселенный тождественный в диспетчер объектов.
$barCategory = $entityManager->find(
Category::class,
CategoryTestFixture::$barCategory->getId()
);
$barCategory->setName('Another name');
$entityManager->flush();
$entityManager->clear();
Вы не помечать вопрос с Symfony, но прочитав здесь: https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#sharing-objects-between-fixtures может дать вам некоторые идеи. – Cerad
Ну, я не потому, что я не работаю с Symfony там :) Я использую Doctrine также для Nette framework. Тем не менее, я, наконец, оказался в этом подходе Symfony, поэтому спасибо :) – amik