Search code examples
symfonyfixtures

Multiple files for Doctrine Fixtures for Symfony 3


I'm using the bundle Doctrine:Fixtures to load an example of bbdd throw the Entitys and since I work alone in the project it's ok.

But now, I got a colleague in my project and we were wondering if it's possible to set up a different files for the loading.

I got my own file of fixtures associated in git and I don't want him modifying this file. I would like to have an special file just for him that will allows him to modify whenever he wants this file of fixtures. So, anyone can have his owns records in the init of the bbdd.

If it's not possible with multiple files, could be possible in another way?

http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html


Solution

  • You can load specific fixture files using the --fixture flag: php app/console doctrine:fixtures:load --fixture=/src/BundleName/DataFixtures/ORM/Fixture.php

    Or, you could add a Fixtures.php.dist file with some working examples, then use .gitignore to ignore Fixtures.php.

    Then add a command into your build (or in composer scripts), and/or your documentation to copy this .dist file to Fixtures.php when checking out the project.

    Another method if you're doing BDD is to create a Helper class that can be used in your Context to create and persist entities as you need them in tests. This would allow you to create only specifics needed for the test. All it really needs is the EntityManager so it may be simpler than pre-defining all the fixtures up front.

    You can use Faker to generate realistic entities.

    class AbstractFixtureHelper implements ContainerAwareInterface
    {
        /**
         * @var Generator
         */
        protected $faker;
    
        /**
         * @var ContainerInterface
         */
        protected $container;
    
        public function __construct()
        {
            $this->faker = Factory::create();
        }
    
        /**
         * @param ContainerInterface|null $container
         * @return void
         */
        public function setContainer(ContainerInterface $container = null)
        {
            $this->container = $container;
        }
    
        /**
         * @return EntityManager
         */
        protected function getEntityManager()
        {
            return $this->container->get('doctrine.orm.entity_manager');
        }
    }
    

    Then for different entities - in this example, a user:

    class UserFixtureHelper extends AbstractFixtureHelper
    {
        public function createUser()
        {
            $user = new User();
            $user->setEmail($this->faker->email);
            $this->getEntityManager()->persist($user);
            $this->getEntityManager()->flush();
    
            return $user;
        }
    }
    

    Then in your Context, inject the UserFixtureHelper and create directly in the scenario steps.

    /**
    * @Given there is a User who XXX
    */
    public function thereIsAUser()
    {
        $user = $this->userFixtureHelper->createUser();
    }