在我们的应用程序中,我们将实体设置为这些固定装置的静态属性,以便可以轻松地在测试中使用它们。
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();
此外,您可以引用它们的所有属性,而不仅仅是 id。因此,如果您想断言,您的 api 返回了正确的类别,您可以这样做。
$this->assertArraySubset([
[
'id' => CategoryTestFixture::$fooCategory->getId(),
'name' => CategoryTestFixture::$fooCategory->getName(),
],
[
'id' => CategoryTestFixture::$barCategory->getId(),
'name' => CategoryTestFixture::$barCategory->getName(),
]
], $apiResponseData);
如果您只想为一个测试用例修改数据,请使用夹具的属性来修改数据库,然后清除 EM,这样您就不会在实体管理器中使用已经填充的身份映射创建副作用。
$barCategory = $entityManager->find(
Category::class,
CategoryTestFixture::$barCategory->getId()
);
$barCategory->setName('Another name');
$entityManager->flush();
$entityManager->clear();