2017-05-02 3 views
0

J'apprends le test de code (TDD) et je me demande ce qui devrait être testé pour des entités simples dans Symfony?Que devrait-on tester (TDD) dans des entités simples?

De la documentation officielle:

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

Deuxième:

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

Je pensais que je devais créer un dossier de l'entité et dans le fichier 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()); 
    } 
} 

Alors ... Dans TDD Je devrais tester tous les champs? Pour l'entité du produit, je devrais tester le nom, le prix et la description?

Si oui, comment traiter le refactoring? Dans ces cas, je dois utiliser dans toutes les méthodes "$ product = new Product();";

Pour un champ de nom, je pourrais avoir besoin de faire un autre test? Quelle?

Dois-je également tester des relations ou le faire dans des tests fonctionnels?

+4

Si vous codez d'abord et ensuite écrivez les tests, ce n'est pas TDD ... BTW, TDD s'assure que vous avez un test pour tout ce que vous avez écrit, donc vous devriez créer un test pour tout ce que vous voulez écrire. –

+0

@GabrielHeming Je sais, mais je suis en train d'apprendre, alors je demande comment cela devrait ressembler à une entité. Je voulais donner un exemple de l'apparence de l'entité dans Symfony, car tout le monde ne connaît pas ce framework. La documentation n'a rien à voir avec TDD, alors j'ai donné les tags "testing et unit-testing" pour que les développeurs d'autres langues me disent comment utiliser TDD pour les entités. – lorumu

+0

Jetez un coup d'œil au dojo de codage TDD. Il y a des exemples/exercices pour tout type de langue qui a un test d'unité. –

Répondre

0

C'est une bonne pratique pour Entities d'avoir aucune logique (complexe) à l'intérieur. En fait, cela devrait représenter votre modèle. Et comme il n'y a pas de logique, il n'y a pas grand chose à tester en réalité. Lorsque vous vérifiez Symfony Demo app vous ne trouverez aucun test pour les entités et je crois que c'est fait de cette façon intentionnellement. Si votre application n'est pas la seule à utiliser la base de données, je considérerais écrire des tests fonctionnels pour les entités qui vous assureront que quelqu'un d'autre n'a pas changé la structure de base de données (par exemple en supprimant la colonne dans la table). L'une des façons d'y arriver est en cours d'exécution d'une simple requête sur la table (entité) que vous testez:

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

Il n'y a pas l'affirmation ici, mais ce lèveront une exception lorsque la définition d'entité ne correspond pas à la base de données

+1

Les modèles anémiques sont certainement une pratique courante, mais pas nécessairement une bonne. https://martinfowler.com/bliki/AnemicDomainModel.html – Gerry

+0

Je comprends la théorie derrière cela, mais j'ai peur que ce soit difficile à implémenter dans l'écosystème Symfony & Doctrine.Doctrine n'appelle jamais le constructeur d'Entity (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/architecture.html#entities) donc faire l'injection de dépendances est difficile et je ne peux pas Imaginez n'importe quelle logique complexe sans dépendances. Pouvez-vous indiquer les grands projets de Symfony qui mettent en œuvre cette théorie? –

+0

@Gerry, les modèles anémiques ne sont pas bons du point de vue de la programmation orientée objet. – Fabio