Comment utiliser les Fixtures avec Doctrine2 & Symfony2
Par Francis Besset le dimanche 12 décembre 2010 - Symfony | Lien permanent

Ça fait maintenant un bon mois que je développe Apercite avec Symfony2. En réalité, je devrais dire que jusqu'à présent j'ai avancé à petit pas, car c'est un nouveau framework, encore en cours de développement et sa documentation n'est pas forcément très exhaustive.
C'est pour cela que je souhaite faire ce billet, pour vous parler des Fixtures.
Lorsque vous développez une application et que celle-ci interagit avec une base de données, il y a fort à parier pour que votre base de données doit contenir certaines entrées de base comme par exemple, la configuration du projet, des données qui changent très peu (pour ma part il s'agit des abonnements par exemple). Dans ce cas à chaque construction de la base de données, vous devrez insérer les données une à une systématiquement.
D'ailleurs lors de la mise en place de tests fonctionnels et unitaires, ça va être un peu galère non ?
Création des fixtures :
Lorsque vous devrez créer des fixtures pour vos Bundles (n'oubliez pas que votre application est aussi un Bundle), vous devrez suivre cette procédure :
- Créer le dossier DataFixtures dans le dossier de votre Bundle.
- Créer le dossier ORM dans le dossier DataFixtures que vous venez de créer.
- Vous devrez ensuite créer un fichier avec l'extension PHP. Pour ma part, il est actuellement nommé SubscriptionData.php. Et voici ce qu'il contient :
<?php
namespace Application\AperciteBundle\DataFixtures\ORM;
use Application\AperciteBundle\Entity\Subscription;
use Doctrine\Common\DataFixtures\FixtureInterface;
class SubscriptionData implements FixtureInterface
{
public function load($manager)
{
$subscription = new Subscription();
$subscription->setPrice(0.99);
$subscription->setDuration('24 hours');
$subscription->setPosition(1);
$manager->persist($subscription);
$manager->flush();
}
}
Vous pouvez par ailleurs, constater que les fixtures sur Symfony2 sont sous forme de classes namespacées.
Votre classe doit obligatoirement implémenter Doctrine\Common\DataFixtures\FixtureInterface. Cette implémentation oblige votre classe à avoir une méthode public load prenant en paramètre la variable $manager qui vous servira à enregistrer les fixtures dans votre base de données. Assurez-vous aussi d'avoir téléchargé le code de Doctrine Data-Fixtures.
Tests fonctionnels et unitaires avec PHPUnit :
Lorsque vous créez vos tests, vous devez reseter vos fixtures. Pour cela, je vais vous offre un bout de code qui va vous être fort utile.
<?php
namespace Application\AperciteBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\DoctrineBundle\Command\LoadDataFixturesDoctrineCommand;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
class FrontendControllerTest extends WebTestCase
{
protected function setUp()
{
$fixtures = new LoadDataFixturesDoctrineCommand();
$fixtures->setApplication(new Application($this->kernel));
$fixtures->run(
new ArrayInput(array(
'doctrine:data:load',
)),
new NullOutput()
);
}
}
La méthode setUp est appelée à chaque test avec PHPUnit. Cette méthode vous assure d'avoir des données toutes fraîches à chaque test. Il y a peut-être un moyen plus élégant d'obtenir la console dans les tests mais j'avoue ne pas avoir trouvé.




Commentaires
Just a fix. Replace use Symfony\Bundle\DoctrineBundle\Command\LoadDataFixturesDoctrineCommand; by use Symfony\Bundle\DoctrineFixturesBundle\Command\LoadDataFixturesDoctrineCommand;
Je trouve qu'on perd quelque chose si on ne peut pas loader des fixtures à partir d'un fichier texte comme ds sf1.4 ?
Je ne peut pas croire que cela ne soit pas prévu, il y a surement un moyen simple de faire ça
avec yml c'est ici :
http://www.strangebuzz.com/post/201...
ça m'étonnait de FB !