儿童计数取决于测试方法
Children count depends on method in test
在试验自引用 ManyToOne 实体时,我发现子实体的数量取决于用于查找父实体的方法。如果使用存储库,则测试失败并显示 Failed asserting that 1 matches expected 2
。如果改为使用 DQL,则测试成功。请参阅下面测试部分中的 testTwoKids()
。我已经在调试中确认在这两种情况下数据库中的实际计数都是 2。
我猜实体定义有问题。
实体:
class Category
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @ORM\Column(name="name", type="string", nullable=false)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
**/
private $children;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children", cascade={"persist","remove"})
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
private $parent;
public function __construct() {
$this->children = new ArrayCollection();
}
public function addChildren($child)
{
$this->children[] = $child;
return $this;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function setParent($parent)
{
$this->parent = $parent;
}
public function getParent()
{
return $this->parent;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add children
*
* @param \AppBundle\Entity\Category $children
* @return Category
*/
public function addChild($child)
{
$this->children->add($child);
$child->setParent($this);
return $this;
}
/**
* Remove children
*
* @param \AppBundle\Entity\Category $children
*/
public function removeChild(\AppBundle\Entity\Category $children)
{
$this->children->removeElement($children);
}
/**
* Get children
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
}
测试
class CategoryTest extends KernelTestCase
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* {@inheritDoc}
*/
public function setUp()
{
self::bootKernel();
$this->em = static::$kernel->getContainer()
->get('doctrine')
->getManager()
;
$product = new \AppBundle\Entity\Product();
$product->setName('foo');
$this->em->persist($product);
$cat = new \AppBundle\Entity\Category();
$cat->setName('Hook');
$child = new \AppBundle\Entity\Category();
$child->setName('Dry');
$child->setParent($cat);
$this->em->persist($child);
$this->em->flush();
}
public function testTwoKids()
{
$c = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => 'Hook']);
$cat = new \AppBundle\Entity\Category();
$cat->setName('Wet');
$this->em->persist($cat);
$c->addChild($cat);
$this->em->persist($c);
$this->em->flush();
/* this returns 1 */
$c2 = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => 'Hook']);
$children = $c2->getChildren();
$this->assertEquals(2, count($children));
/* this returns 2 */
// $id = $c2->getId();
// $children = $this->em->createQuery("SELECT c FROM AppBundle:Category c WHERE c.parent = $id")
// ->getResult();
// $this->assertEquals(2, count($children));
}
也请在上次冲水后尝试 运行 $this->em->clear()
。可能是Doctrine entity manager缓存或者结果缓存导致的。
在试验自引用 ManyToOne 实体时,我发现子实体的数量取决于用于查找父实体的方法。如果使用存储库,则测试失败并显示 Failed asserting that 1 matches expected 2
。如果改为使用 DQL,则测试成功。请参阅下面测试部分中的 testTwoKids()
。我已经在调试中确认在这两种情况下数据库中的实际计数都是 2。
我猜实体定义有问题。
实体:
class Category
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @ORM\Column(name="name", type="string", nullable=false)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
**/
private $children;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children", cascade={"persist","remove"})
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
private $parent;
public function __construct() {
$this->children = new ArrayCollection();
}
public function addChildren($child)
{
$this->children[] = $child;
return $this;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function setParent($parent)
{
$this->parent = $parent;
}
public function getParent()
{
return $this->parent;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add children
*
* @param \AppBundle\Entity\Category $children
* @return Category
*/
public function addChild($child)
{
$this->children->add($child);
$child->setParent($this);
return $this;
}
/**
* Remove children
*
* @param \AppBundle\Entity\Category $children
*/
public function removeChild(\AppBundle\Entity\Category $children)
{
$this->children->removeElement($children);
}
/**
* Get children
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
}
测试
class CategoryTest extends KernelTestCase
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* {@inheritDoc}
*/
public function setUp()
{
self::bootKernel();
$this->em = static::$kernel->getContainer()
->get('doctrine')
->getManager()
;
$product = new \AppBundle\Entity\Product();
$product->setName('foo');
$this->em->persist($product);
$cat = new \AppBundle\Entity\Category();
$cat->setName('Hook');
$child = new \AppBundle\Entity\Category();
$child->setName('Dry');
$child->setParent($cat);
$this->em->persist($child);
$this->em->flush();
}
public function testTwoKids()
{
$c = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => 'Hook']);
$cat = new \AppBundle\Entity\Category();
$cat->setName('Wet');
$this->em->persist($cat);
$c->addChild($cat);
$this->em->persist($c);
$this->em->flush();
/* this returns 1 */
$c2 = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => 'Hook']);
$children = $c2->getChildren();
$this->assertEquals(2, count($children));
/* this returns 2 */
// $id = $c2->getId();
// $children = $this->em->createQuery("SELECT c FROM AppBundle:Category c WHERE c.parent = $id")
// ->getResult();
// $this->assertEquals(2, count($children));
}
也请在上次冲水后尝试 运行 $this->em->clear()
。可能是Doctrine entity manager缓存或者结果缓存导致的。