2017-01-22 50 views
0

我面臨着Doctrine Data Fixtures的一個問題:當我使用Fixtures插入一些數據來運行驗收測試時,我能否以某種方式確保特定實體被持久化並持續使用特定ID?用數據夾具管理實體ID

例如,我創建了幾個樣本用戶,然後運行驗收測試,編輯其中一個用戶。我需要知道這個測試用例的用戶ID。 處理這個問題的最佳做法是什麼? 是否有可能對由燈具創建的某些實體進行硬編碼,或者是否應該將生成的ID存儲到單獨的表,文件等中以查找請求的實體?或者還有其他最佳做法嗎?

在此先感謝。

+0

你沒有標記與Symfony的你的問題,但經過這裏閱讀:https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#sharing-objects-between-fixtures可能給你一些想法。 – Cerad

+0

那麼我沒有,因爲我沒有在Symfony那裏工作:)我也爲Nette框架使用Doctrine。然而,我終於結束了這個Symfony的方法,所以謝謝:) – amik

回答

4

在我們的應用程序中,我們將實體設置爲這些燈具的靜態屬性,因此它們可以很容易地從測試中使用。

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; 
    } 

} 

有一些重要的規則是:

  • 確保你不叫$em->clear()的電腦燈,這樣你就可以直接使用實體其他附着物類。
  • 致電$em->clear()一旦加載了夾具,它們不會影響您的測試。
  • 在每次測試之前,請複製準備好的數據庫,並將該副本用於測試,而不是「模板數據庫」。所以你可以安全地修改數據。它可以進一步優化,但這是最直接的解決方案。
  • 不要合併或嘗試註冊爲管理測試中的原始設備。

現在,你有燈具創建的,你用他們喜歡這個

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

此外,您還可以參考他們的所有屬性,不僅IDS。所以,如果你想讓我斷言,你的API返回了正確的類別,你可以這樣做。

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

,如果你想修改數據只是一個測試用例,使用固定的屬性來修改數據庫,然後清除EM aftewards,所以你不創建副作用,在已填充身份地圖實體經理。

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

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

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

有趣的想法,但我不明白這是如何比Symfony的參考方法更好。我也不太清楚清除EM的幫助,不應該已經加載的實體已經被Doctrine正確映射,所以如果我從引用修改它,所有其他引用(「引用變量」)指向相同,修改實體? – amik