具有Symfony+Doctrine的特定于环境的数据固定装置



使用Smyfony2和Doctrin2,可以使用以下示例创建数据固定装置:http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html

我希望能够将这个概念用于测试,这样设置/拆卸就可以为功能测试创建一个纯测试数据环境。我该如何在功能测试期间运行一组特定的仅限测试的固定装置,以及如何将这些固定装置与我的标准固定装置分离,以便控制台命令忽略它们?

这样做的方法似乎是复制原理的功能:fixtures控制台命令并将测试fixtures存储在其他地方。有人有更好的解决方案吗?

按目录划分fixture的另一种选择是使用自定义fixture类。然后,您的fixture类将扩展这个类,并指定它将实际加载的环境

<?php
use DoctrineCommonDataFixturesFixtureInterface;
use DoctrineCommonPersistenceObjectManager;
use SymfonyComponentDependencyInjectionContainerAwareInterface;
use SymfonyComponentDependencyInjectionContainerInterface;
use SymfonyComponentHttpKernelKernelInterface;
/**
 * Provides support for environment specific fixtures.
 *
 * This container aware, abstract data fixture is used to only allow loading in
 * specific environments. The environments the data fixture will be loaded in is
 * determined by the list of environment names returned by `getEnvironments()`.
 *
 * > The fixture will still be shown as having been loaded by the Doctrine
 * > command, `doctrine:fixtures:load`, despite not having been actually
 * > loaded.
 *
 * @author Kevin Herrera <kevin@herrera.io>
 */
abstract class AbstractDataFixture implements ContainerAwareInterface, FixtureInterface
{
    /**
     * The dependency injection container.
     *
     * @var ContainerInterface
     */
    protected $container;
    /**
     * {@inheritDoc}
     */
    public function load(ObjectManager $manager)
    {
        /** @var KernelInterface $kernel */
        $kernel = $this->container->get('kernel');
        if (in_array($kernel->getEnvironment(), $this->getEnvironments())) {
            $this->doLoad($manager);
        }
    }
    /**
     * {@inheritDoc}
     */
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
    /**
     * Performs the actual fixtures loading.
     *
     * @see DoctrineCommonDataFixturesFixtureInterface::load()
     *
     * @param ObjectManager $manager The object manager.
     */
    abstract protected function doLoad(ObjectManager $manager);
    /**
     * Returns the environments the fixtures may be loaded in.
     *
     * @return array The name of the environments.
     */
    abstract protected function getEnvironments();
}

你的固定装置最终会是这样的:

<?php
namespace VendorBundleExampleBundleDataFixturesORM;
use AbstractDataFixture;
use DoctrineCommonPersistenceObjectManager;
/**
 * Loads data only on "prod".
 */
class ExampleData extends AbstractDataFixture
{
    /**
     * @override
     */
    protected function doLoad(ObjectManager $manager)
    {
        // ... snip ...
    }
    /**
     * @override
     */
    protected function getEnvironments()
    {
        return array('prod');
    }
}

我认为这应该同时适用于ORM和ODM数据固定装置。

最简单的方法是将设备放入不同的文件夹,然后使用php app/console doctrine:fixtures:load --fixtures=../src/Acme/TestBundle/DataFixtures/ORM/test命令加载它们。fixtures选项必须指向应用程序文件夹的相对路径!

然后,您可以将数据拆分为初始、测试等,也可以根据自己的喜好创建开发、测试、暂存、生产固定装置。

如果你想把它们混合在一起,我不知道有什么比我所做的更好的解决方案了:我创建了一个"templates"文件夹,所有的fixture都位于其中。在我的dev文件夹中,我创建一个类,它从template扩展适当的fixture类,并调整需要调整的内容(比如覆盖getOrder方法)。这并不完美,我想人们可以考虑扩展fixtures:load命令以采用多条路径,但它对我有效。

相关内容

  • 没有找到相关文章

最新更新