Symfony Doctrine 关系在 PhpUnit 测试中为空
Symfony Doctrine relationship empty in PhpUnit test
我有一个带有 User
实体的 Symfony 应用程序,该实体与 Cat
实体存在多对多关系。我还有一个 PhpUnit 测试,它检查从 1 个用户删除一只猫(属于 2 个用户)实际上并没有删除猫:
public function testDeletingACatBelongingToTwoUsersOnlyDeletesTheAssociationNotTheCat()
{
$cat = $this->createCat();
// Associate with user 1
$user1 = new User();
$user1->setEmail('test@example.com');
$user1->setPassword('pwdpwd');
$user1->addCat($cat);
$this->em->persist($user1);
// Associate with user 2
$user2 = new User();
$user2->setEmail('another@example.com');
$user2->setPassword('pwdpwd');
$user2->addCat($cat);
$this->em->persist($user2);
$this->em->flush();
// Sanity check:
$this->assertCount(1, $user1->getCats()); // PASS
$this->assertCount(1, $user2->getCats()); // PASS
$this->assertCount(2, $cat->getUsers()); // FAIL (0)
// ... perform the test (not shown here)
}
private function createCat(): Cat
{
$cat = new Cat();
$cat->setName($this->name);
$this->em->persist($cat);
$this->em->flush();
return $cat;
}
我的问题是,为什么 $cat->getUsers()
return 0
在我的测试中?在运行时它没有,它 return 是正确的值。只是在测试中才 returns 0
.
以下是我的实体的相关摘录,由 Symfony 自动生成:
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
*/
class User implements UserInterface
{
/**
* @ORM\ManyToMany(targetEntity=Cat::class, inversedBy="users")
*/
private $cats;
/**
* @return Collection|Cat[]
*/
public function getCats(): Collection
{
return $this->cats;
}
public function addCat(Cat $cat): self
{
if (!$this->cats->contains($cat)) {
$this->cats[] = $cat;
}
return $this;
}
public function removeCat(Cat $cat): self
{
$this->cats->removeElement($cat);
return $this;
}
}
/**
* @ORM\Entity(repositoryClass=CatRepository::class)
*/
class Cat
{
/**
* @ORM\ManyToMany(targetEntity=User::class, mappedBy="cats")
*/
private $users;
/**
* @return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}
}
原因是,collection没有和数据库同步,主反双方也没有自动同步。
您的用户实体的类别条目可能 将持久保存到数据库中(虽然我缺少一些级联语句,但我知道什么)。创建类别时,用户的 collection 为空(显然),然后用户将类别添加到数据库中的 many-to-many 关系。
但是,collection 是普通的 collection。如果您从数据库加载类别,它将是一个 lazy-loaded PersistentCollection(或类似的东西),它只会在访问时从数据库中获取项目(延迟加载的定义)。你的测试代码有普通的 collection (因为你自己创建了 object)。
不太确定,如果它会工作,但你可以尝试刷新猫 ($em->refresh($cat);
) 不过我不太确定,如果它会取代 collection。或者,你可以让你的 User::addCat
它也调用 $cat->addUser($this)
(你可能必须添加它,当心无限递归,它已经应该被“包含”检查阻止。)。
我有一个带有 User
实体的 Symfony 应用程序,该实体与 Cat
实体存在多对多关系。我还有一个 PhpUnit 测试,它检查从 1 个用户删除一只猫(属于 2 个用户)实际上并没有删除猫:
public function testDeletingACatBelongingToTwoUsersOnlyDeletesTheAssociationNotTheCat()
{
$cat = $this->createCat();
// Associate with user 1
$user1 = new User();
$user1->setEmail('test@example.com');
$user1->setPassword('pwdpwd');
$user1->addCat($cat);
$this->em->persist($user1);
// Associate with user 2
$user2 = new User();
$user2->setEmail('another@example.com');
$user2->setPassword('pwdpwd');
$user2->addCat($cat);
$this->em->persist($user2);
$this->em->flush();
// Sanity check:
$this->assertCount(1, $user1->getCats()); // PASS
$this->assertCount(1, $user2->getCats()); // PASS
$this->assertCount(2, $cat->getUsers()); // FAIL (0)
// ... perform the test (not shown here)
}
private function createCat(): Cat
{
$cat = new Cat();
$cat->setName($this->name);
$this->em->persist($cat);
$this->em->flush();
return $cat;
}
我的问题是,为什么 $cat->getUsers()
return 0
在我的测试中?在运行时它没有,它 return 是正确的值。只是在测试中才 returns 0
.
以下是我的实体的相关摘录,由 Symfony 自动生成:
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
*/
class User implements UserInterface
{
/**
* @ORM\ManyToMany(targetEntity=Cat::class, inversedBy="users")
*/
private $cats;
/**
* @return Collection|Cat[]
*/
public function getCats(): Collection
{
return $this->cats;
}
public function addCat(Cat $cat): self
{
if (!$this->cats->contains($cat)) {
$this->cats[] = $cat;
}
return $this;
}
public function removeCat(Cat $cat): self
{
$this->cats->removeElement($cat);
return $this;
}
}
/**
* @ORM\Entity(repositoryClass=CatRepository::class)
*/
class Cat
{
/**
* @ORM\ManyToMany(targetEntity=User::class, mappedBy="cats")
*/
private $users;
/**
* @return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}
}
原因是,collection没有和数据库同步,主反双方也没有自动同步。
您的用户实体的类别条目可能 将持久保存到数据库中(虽然我缺少一些级联语句,但我知道什么)。创建类别时,用户的 collection 为空(显然),然后用户将类别添加到数据库中的 many-to-many 关系。
但是,collection 是普通的 collection。如果您从数据库加载类别,它将是一个 lazy-loaded PersistentCollection(或类似的东西),它只会在访问时从数据库中获取项目(延迟加载的定义)。你的测试代码有普通的 collection (因为你自己创建了 object)。
不太确定,如果它会工作,但你可以尝试刷新猫 ($em->refresh($cat);
) 不过我不太确定,如果它会取代 collection。或者,你可以让你的 User::addCat
它也调用 $cat->addUser($this)
(你可能必须添加它,当心无限递归,它已经应该被“包含”检查阻止。)。