2017-01-22 6 views
0

Ich stehe vor einem Problem mit Doctrine Data Fixtures: Wenn ich einige Daten mit Fixtures zum Ausführen von Akzeptanztests einfüge, kann ich irgendwie sicherstellen, dass bestimmte Entitäten persistent sind und mit einer bestimmten ID bestehen?Entitäts-IDs mit Daten-Fixtures verwalten

Zum Beispiel, ich erstelle mehrere Beispiel Benutzer, dann führen Sie einen Abnahmetest bearbeiten einen der Benutzer. Ich muss die ID des Benutzers für diesen Testfall kennen. Was ist die beste Vorgehensweise, um damit umzugehen? Ist es möglich, IDs für einige von Fixtures erstellte Entitäten fest zu codieren, oder sollte ich generierte IDs in einer separaten Tabelle, Datei usw. speichern, um die angeforderte Entität zu finden? oder gibt es noch andere Best Practices?

Vielen Dank im Voraus.

+0

Sie haben Ihre Frage mit Symfony nicht markieren, sondern durch hier zu lesen: https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#sharing-objects-between-fixtures könnte Ihnen einige Ideen. – Cerad

+0

Nun, ich habe nicht, weil ich nicht mit Symfony arbeite :) Ich benutze Doctrine auch für Nette Framework. Aber schließlich endete ich mit diesem Ansatz von Symfony, also danke :) – amik

Antwort

4

In unserer Anwendung setzen wir die Entitäten in statische Eigenschaften dieser Fixtures, so dass sie einfach aus Tests verwendet werden können.

class CategoryTestFixture 
    extends \Doctrine\Common\DataFixtures\AbstractFixture 
    implements 
     \Doctrine\Common\DataFixtures\OrderedFixtureInterface, 
     \Symfony\Component\DependencyInjection\ContainerAwareInterface 
{ 

    /** @var \My\Category */ 
    public static $fooCategory; 

    /** @var \My\Category */ 
    public static $barCategory; 

    /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ 
    private $container; 

    public function load(ObjectManager $manager) 
    { 
     self::$fooCategory = new Category('Foo'); 
     $entityManager->persist(self::$fooCategory); 

     self::$barCategory = new Category('Bar'); 
     $entityManager->persist(self::$barCategory); 

     $entityManager->flush(); 
    } 

    // you can inject the container, 
    // so you can use your Facades in fixtures 

    public function getContainer(): ContainerInterface 
    { 
     return $this->container; 
    } 

    public function setContainer(ContainerInterface $container = null) 
    { 
     $this->container = $container; 
    } 

} 

Es gibt einige wichtige Regeln dazu:

  • Stellen Sie sicher, rufen Sie nicht $em->clear() in Ihrer Spiele, so dass Sie direkt die Objekte in anderen Vorrichtungen Klassen verwenden können.
  • Rufen Sie $em->clear() an, sobald die Geräte geladen sind, so dass sie Ihre Tests nicht beeinflussen.
  • Erstellen Sie vor jedem Test eine Kopie der vorbereiteten Datenbank und verwenden Sie diese Kopie für Ihre Tests, nicht die "Template-Datenbank". So können Sie die Daten sicher ändern. Es kann weiter optimiert werden, aber dies ist die einfachste Lösung.
  • Nicht zusammenführen oder versuchen, die ursprünglichen Fixtures in Ihren Tests als verwaltet zu registrieren.

Jetzt haben Sie die Armaturen erstellt haben, verwenden Sie sie wie diese

$id = CategoryTestFixture::$barCategory->getId(); 

Auch können Sie alle ihre Eigenschaften verweisen, nicht nur ids. Also wenn du sagen möchtest, dass deine API die richtigen Kategorien zurückgegeben hat, könntest du es so machen.

$this->assertArraySubset([ 
    [ 
     'id' => CategoryTestFixture::$fooCategory->getId(), 
     'name' => CategoryTestFixture::$fooCategory->getName(), 
    ], 
    [ 
     'id' => CategoryTestFixture::$barCategory->getId(), 
     'name' => CategoryTestFixture::$barCategory->getName(), 
    ] 
], $apiResponseData); 

und wenn Sie wollen, um die Daten ändern nur für einen Testfall, verwenden Sie die Eigenschaften der Halterung Datenbank zu ändern und dann aftewards klar EM, so dass Sie in keine Nebenwirkungen, die mit bereits besiedelten Identität Karte erstellen der Entity Manager.

$barCategory = $entityManager->find(
    Category::class, 
    CategoryTestFixture::$barCategory->getId() 
); 

$barCategory->setName('Another name'); 

$entityManager->flush(); 
$entityManager->clear(); 
+0

Interessante Idee, aber ich sehe nicht, wie das ist besser als Symfony's Referenzen Ansatz. Ich bekomme auch nicht ganz klar, wie Clearing-EM hilft, sollten bereits geladene Entitäten nicht schon von Doctrine richtig zugeordnet werden, so dass, wenn ich es von einer Referenz verändere, alle anderen Referenzen ("verweisende Variablen") auf denselben, modifizierten zeigen Entität? – amik