Les fixtures ou données de tests permettent au développeur d’initialiser les données de la base de données dans un état connu. Par exemple, pour l’entité User, il serait possible de charger plusieurs utilisateurs avec différents rôles et caractéristiques. On pourrait créer un administrateur, un utilisateur standard et un utilisateur avec un accès désactivé. Par la suite, il serait possible d’écrire des tests fonctionnels afin de vérifier que notre page d’authentification (login) fonctionne bien avec tous ces types d’utilisateurs.
Dans bien des cas, il faudra recharger les fixtures entre chaque test. De cette manière, les effets de bord seront évités. Un état stable et connu sera initialisé entre chaque test.
Avec Symfony et Doctrine, il est facile de mettre en place des fixtures. Les fixtures héritent de la classe AbstractFixture et sont déposées dans le dossier /DataFixtures/ORM. Si l’ordre de chargement des fixtures est important, il est aussi possible d’implémenter l’interface OrderedFixtureInterface.
Configuration du bundle DoctrineFixturesBundle
Avant de faciliter la gestion des fixtures, il est conseillé de mettre en place le DoctrineFixturesBundle. Voici la procédure à suivre :
- DoctrineFixturesBundle (The Symfony Bundles Documentation)
- http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html
Exemple de fixture pour Doctrine et Symfony
Le code suivant présente une classe qui permet de charger des entités Cegep dans la base de données.
On débute par définir l’espace de nom (namespace), par la suite, on indique les classes à charger avec le mot clé use, finalement, la classe est définie. Cette classe doit hériter de AbstractFixture et fournir une méthode load. C’est dans la méthode load que les entités seront créées et sauvegardées vers la base de données.
Si plusieurs classes de fixtures sont nécessaires, il sera peut-être important de définir l’ordre de chargement (créer les utilisateurs avant de créer les commentaires associés à ces utilisateurs). L’interface OrderedFixtureInterface vous obligera à définir la méthode getOrder qui devra retourner l’ordre de chargement de votre classe.
/src/Acme/Bundle/ApiBundle/DataFixtures/ORM/LoadCegepData.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<?php namespace Acme\AppBundle\DataFixtures\ORM; use Acme\AppBundle\Entity\Cegep; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; class LoadCegepData extends AbstractFixture implements OrderedFixtureInterface { /** * Load data fixtures with the passed EntityManager * @param ObjectManager $manager */ public function load(ObjectManager $manager) { $cegep = new Cegep(); $cegep->setName("Cégep de Sainte-Foy"); $cegep->setAddress("123 chemin Ste-Foy"); $cegep->setPostalCode("G1V 1T3"); $cegep->setPhone("418-659-6600"); $cegep->setWebUrl("http://www.cegep-ste-foy.qc.ca"); $this->addReference('cegep-csf', $cegep); $manager->persist($cegep); $cegep = new Cegep(); $cegep->setName("Cegep 1"); $cegep->setAddress("1 rue"); $cegep->setPostalCode("G1M 1P1"); $cegep->setPhone("418 659 1111"); $cegep->setWebUrl("www.cegep-1.qc.ca"); $cegep->setCreatedAt(new \DateTime('now')); $manager->persist($cegep); $manager->flush(); } /** * Get the order of this fixture * @return integer */ public function getOrder() { return 1; } } |
addReference et getReference
La méthode addReference permet au développeur de sauvegarder une référence vers une entité. Par exemple, on sauvegarde une référence d’un utilisateur lors de sa création et on utilise cette référence lors de la création d’un commentaire pour cet utilisateur :
1 2 3 4 5 6 |
# LoadUserData.php $user = new User(); $user->setName("Utilisateur Admin"); $this->addReference('user-admin', $user); |
1 2 3 4 5 6 7 |
# LoadCommentData.php $userAdmin = $this->getReference('user-admin'); $comment = new Comment(); $comment->setBody("Mon commentaire 1"); $comment->setUser($userAdmin); |
persist et flush
La méthode load nous donne accès à un objet de type ObjectManager. Cet objet permet de sauvegarder nos entités vers la base de données.
La méthode persist indique à Doctrine que l’entité devra être sauvegardée.
1 |
$manager->persist($cegep); |
La méthode flush sauvegarde toutes les entités marquées pour la sauvegarde avec persist.
C’est lors du flush que les requêtes SQL sont lancées.
1 |
$manager->flush(); |
Chargement des fixtures
Pour réinitialiser la base de données avec les données de vos fixtures, vous pouvez lancer la commande fixture:load :
1 2 3 |
$ bin/console doctrine:fixtures:load Careful, database will be purged. Do you want to continue y/N ? |
Article top, merci !