2012-08-05 59 views
19

随着Smyfony2和Doctrin2,数据固定装置可以使用下面的示例中创建可以为功能测试创建一个纯粹的测试数据环境。如何才能在功能测试期间运行一组特定的仅用于测试的灯具,以及如何将这些灯具与我的标准灯具分离,以便控制台命令忽略它们?与Symfony的+学说环境的具体数据灯具

看来,这样做的方式是复制教条的功能:夹具控制台命令并将测试夹具存储在别处。有没有人有更好的解决方案?

回答

35

根据目录分解灯具的替代方法是使用自定义灯具类。然后,您的夹具类将扩展此类,并指定将在实际加载的环境

<?php 

use Doctrine\Common\DataFixtures\FixtureInterface; 
use Doctrine\Common\Persistence\ObjectManager; 
use Symfony\Component\DependencyInjection\ContainerAwareInterface; 
use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\HttpKernel\KernelInterface; 

/** 
* 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 <[email protected]> 
*/ 
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 \Doctrine\Common\DataFixtures\FixtureInterface::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 Vendor\Bundle\ExampleBundle\DataFixtures\ORM; 

use AbstractDataFixture; 
use Doctrine\Common\Persistence\ObjectManager; 

/** 
* 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数据装置。

+5

这是天才! – ferdynator 2014-04-04 12:43:01

+2

如何从控制台定义环境?使用'php app/console fixture:load --env = prod'? – xDaizu 2016-02-12 08:57:53

+0

回答自己:Yesh,'php app/console fixture:load --env = prod',与提供的解决方案一起使用:) – xDaizu 2016-04-08 14:13:34

17

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

然后,您可以将数据拆分为初始,测试等,或者根据需要创建开发,测试,分期,产品固件。

如果你想混合起来,我不知道比我做的任何更好的解决方案:我创建一个“模板”文件夹,其中所有灯具驻留在。在我的dev文件夹中,我创建了一个类,从模板中选择适当的夹具类并调整需要调整的内容(如覆盖getOrder方法)。这不是完美的,我想可以考虑扩展灯具:load命令采取多个路径,但它适用于我。

+0

这听起来像一个好的开始。谢谢! – 2012-08-06 22:58:39