Fixture con contenitore di servizi nei test funzionali

A volte può essere utile avere a disposizione il contenitore di servizi nelle fixture usate nei test funzionali. Un caso tipico è l’uso di FOSUserBundle, che mette a disposizione un servizio UserManager per creare utenti, utilizzabile quindi anche per crearli all’interno delle fixture.
Purtroppo la documentazione a riguardo è alquanto avara di informazioni, per cui condivido qui questa soluzione, mostrando un esempio.
Ecco un possibile file di fixture per gli utenti:

<?php
 
namespace Acme\PippoBundle\DataFixtures\ORM;
 
 
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
 
class LoadUserData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
    private $container;
 
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
 
    public function load(ObjectManager $manager)
    {
        $userManager = $this->container->get('fos_user.user_manager');
 
        $user1 = $userManager->createUser();
        $user1
            ->setUsername('pippo')
            ->setEmail('pippo@example.org')
            ->setFirstName('Mallo')
            ->setLastName('Di Noce')
            ->setBirthday(new \DateTime('1977-07-07'))
            ->setEnabled(true)
            ->setPlainPassword('mallodinoce')
        ;
        $userManager->updateUser($user1, false);
        $manager->persist($user1);
        $this->addReference('user1', $user1);
 
        $manager->flush();
    }
 
    public function getOrder()
    {
        return 1;
    }
}

Questa fixture si può usare in un test in questo modo:

<?php
 
namespace Acme\PippoBundle\Tests\Controller;
 
use Acme\PippoBundle\DataFixtures\ORM\LoadUserData;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader as Loader; // il trucco è qui..
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase
 
class DefaultControllerTest extends WebTestCase
{
    public function setUp()
    {
        $kernel = static::createKernel();
        $kernel->boot();
        $container = $kernel->getContainer();
        $loader = new Loader($container);  // ... e qui
        $loader->addFixture(new LoadUserData);
        $purger = new ORMPurger();
        $executor = new ORMExecutor($this->em, $purger);
        $executor->execute($loader->getFixtures());
    } 
 
    public function testIndex()
    {
        $client = static::createClient();
        $crawler = $client->request('GET', '/');
        $this->assertTrue($client->getResponse()->isSuccessful());
    }
}

One thought on “Fixture con contenitore di servizi nei test funzionali”

  1. Oppure usare il bundle LiipFunctionalTestBundle ed estendere dalla loro classe WebTestCase dove hai a disposizione il metodo loadFixtures(Array) a cui puoi passare tutte le fixture che, se implementano ContainerAwareInterface, hanno a disposizione il container.
    Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>