2017-05-02 25 views
0

我正在學習代碼測試(TDD),並想知道應該在Symfony中爲簡單實體測試什麼?簡單實體中應該測試什麼(TDD)?

從官方文檔:

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Category 
* 
* @ORM\Table(name="category") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository") 
*/ 
class Category 
{ 
    /** 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\Column(name="name", type="string", length=255) 
    */ 
    private $name; 

    /** 
    * @ORM\OneToMany(targetEntity="Product", mappedBy="category") 
    */ 
    private $products; 
    /** 
    * Constructor 
    */ 
    public function __construct() 
    { 
     $this->products = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * 
    * @return Category 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    /** 
    * Add product 
    * 
    * @param \AppBundle\Entity\Product $product 
    * 
    * @return Category 
    */ 
    public function addProduct(\AppBundle\Entity\Product $product) 
    { 
     $this->products[] = $product; 

     return $this; 
    } 

    /** 
    * Remove product 
    * 
    * @param \AppBundle\Entity\Product $product 
    */ 
    public function removeProduct(\AppBundle\Entity\Product $product) 
    { 
     $this->products->removeElement($product); 
    } 

    /** 
    * Get products 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getProducts() 
    { 
     return $this->products; 
    } 
} 

二:

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity 
* @ORM\Table(name="product") 
*/ 
class Product 
{ 
    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\Column(type="string", length=100) 
    */ 
    private $name; 

    /** 
    * @ORM\Column(type="decimal", scale=2) 
    */ 
    private $price; 

    /** 
    * @ORM\Column(type="text") 
    */ 
    private $description; 

    /** 
    * @ORM\ManyToOne(targetEntity="Category", inversedBy="products") 
    * @ORM\JoinColumn(name="category_id", referencedColumnName="id") 
    */ 
    private $category; 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * 
    * @return Product 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    /** 
    * Set price 
    * 
    * @param string $price 
    * 
    * @return Product 
    */ 
    public function setPrice($price) 
    { 
     $this->price = $price; 

     return $this; 
    } 

    /** 
    * Get price 
    * 
    * @return string 
    */ 
    public function getPrice() 
    { 
     return $this->price; 
    } 

    /** 
    * Set description 
    * 
    * @param string $description 
    * 
    * @return Product 
    */ 
    public function setDescription($description) 
    { 
     $this->description = $description; 

     return $this; 
    } 

    /** 
    * Get description 
    * 
    * @return string 
    */ 
    public function getDescription() 
    { 
     return $this->description; 
    } 

    /** 
    * Set category 
    * 
    * @param \AppBundle\Entity\Category $category 
    * 
    * @return Product 
    */ 
    public function setCategory(\AppBundle\Entity\Category $category = null) 
    { 
     $this->category = $category; 

     return $this; 
    } 

    /** 
    * Get category 
    * 
    * @return \AppBundle\Entity\Category 
    */ 
    public function getCategory() 
    { 
     return $this->category; 
    } 
} 

我想我不得不創建一個實體的文件夾和文件CategoryTest內:

namespace Tests\AppBundle\Entity; 

use AppBundle\Entity\Tag; 
use AppBundle\Form\DataTransformer\TagArrayToStringTransformer; 
use Doctrine\Common\Persistence\ObjectManager; 
use Doctrine\ORM\EntityRepository; 

class CategoryTest extends \PHPUnit\Framework\TestCase 
{ 
    public function testGetName() 
    { 
     $category = new \AppBundle\Entity\Category(); 
     $category->setName('test'); 
     $this->assertSame('test', $category->getName()); 
    } 
} 

所以......在TDD我應該測試所有領域?對於產品實體,我應該測試名稱,價格和描述?

如果是,如何處理重構?在這些情況下,我必須在所有方法中使用「$ product = new Product();」;

對於名稱字段,我可能需要做另一個測試?什麼?

我還應該測試關係還是在功能測試中做?

+4

如果你先編寫代碼然後編寫測試,這不是TDD ...順便說一句,TDD確保你對你寫的所有東西都有測試,所以你應該爲你想寫的東西創建一個測試。 –

+0

@ GabrielHeming我知道,但我只是在學習,所以我在問這個應該如何尋找一個實體。我想給出一個關於實體在Symfony中的外觀的例子,因爲不是每個人都知道這個框架。這些文檔與TDD無關,所以我給了標籤「測試和單元測試」,以便其他語言的開發人員告訴我如何使用TDD實體。 – lorumu

+0

看一下TDD編碼Dojo。有單元測試的任何種語言的例子/練習。 –

回答

0

這是Entities裏面沒有(複雜)邏輯的好習慣。事實上,它應該只是代表你的模型。而且由於沒有邏輯,所以實際測試並不多。當你檢查Symfony Demo app時,你會發現沒有對實體進行測試,我相信這是故意完成的。

如果您的應用程序不是唯一使用數據庫的應用程序,我會考慮爲實體編寫功能測試,以確保其他人不會在不讓您知道的情況下更改數據庫結構(例如,通過刪除列中的列)。其中一個可能的方式來實現運行表(實體)的簡單查詢您正在測試:

public function checkEntityDefinition($entityName) 
{   $this->em->getRepository($entityName) 
      ->createQueryBuilder('t') 
      ->setMaxResults(1) 
      ->getQuery() 
      ->getArrayResult(); 
} 

這裏沒有說法,但是這將拋出一個異常時,實體定義不匹配數據庫

+1

貧血模型無疑是一種常見的做法,但不一定是好的模式。 https://martinfowler.com/bliki/AnemicDomainModel.html – Gerry

+0

我理解背後的理論,但恐怕很難在Symfony&Doctrine生態系統中實現。Doctrine不曾調用實體的構造函數(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/architecture.html#entities),因此做適當的依賴注入是困難的,我不能想象沒有依賴關係的任何複雜邏輯。你能指出任何大/受歡迎的Symfony實施這個理論的項目嗎? –

+0

@Gerry,僅僅從面向對象的編程觀點來看,_anemic模型不是一個好的選擇。 – Fabio