Symfony 编写功能测试时,将会话中的用户连接到当前EntityManager
我正在为与Symfony 编写功能测试时,将会话中的用户连接到当前EntityManager,symfony,testing,doctrine-orm,functional-testing,Symfony,Testing,Doctrine Orm,Functional Testing,我正在为与用户实体有关系的操作实体编写功能测试: <?php namespace Acme\AppBundle\Entity; /** * Class Action * * @ORM\Table() * @ORM\Entity(repositoryClass="Acme\AppBundle\Repository\ActionRepository") */ class Action { /** * @var int * * @ORM\Col
用户
实体有关系的操作
实体编写功能测试:
<?php
namespace Acme\AppBundle\Entity;
/**
* Class Action
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Acme\AppBundle\Repository\ActionRepository")
*/
class Action
{
/**
* @var int
*
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var \Acme\AppBundle\Entity\User
*
* @ORM\ManyToOne(targetEntity="\Acme\AppBundle\Entity\User", inversedBy="actions")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $createdBy;
}
在控制器中使用以下代码段设置用户:
<?php
namespace Acme\ApiBundle\Controller;
/**
*
* @Route("/actions")
*/
class ActionController extends FOSRestController
{
public function postAction(Request $request)
{
$action = new Action();
$action->setCreatedBy($this->getUser());
return $this->processForm($action, $request->request->all(), Request::METHOD_POST);
}
}
现在,问题是注入的UsernamePasswordToken
包含一个User
实例,该实例与当前的EntityManager
分离,从而导致上述条令错误
我可以将postAction
方法中的$user
对象合并到EntityManager
中,但我不想这样做,因为这意味着我修改工作代码以使测试通过。
我还尝试将测试中的$user
对象合并到EntityManager
中,如下所示:
$em = $client->getContainer()->get('doctrine')->getManager();
$em->merge($user);
但它也不起作用
所以现在,我被卡住了,我真的不知道该怎么做,除了我需要将会话中的用户连接回当前的
EntityManager
您收到的错误消息表明测试客户端容器中包含的EntityManager不知道您的用户实体。这让我相信,在createAuthenticatedClient
方法中检索用户的方式是使用不同的EntityManager
我建议您尝试使用测试内核的EntityManager来检索用户实体。例如,您可以从测试客户端的容器中获得它。感谢您的推文,我来完成给定的答案并(尝试)提出解决方案 问题是您的用户不由EntityManager管理,更简单地说,因为它不是在数据库中注册的真实现有用户 为了解决这个问题,您需要一个真正的(托管的)用户,该用户可以用于您的操作试图创建的关联 因此,您可以在每次执行功能测试用例时创建此用户(并在完成时将其删除),或者在新环境中第一次执行测试用例时仅创建一次 像这样的事情应该可以做到:
/** @var EntityManager */
private $em;
/**
*/
public function setUp()
{
$client = static::createClient();
$this->em = $client->getKernel()
->getContainer()
->get('doctrine');
$this->authClient = $this->createAuthenticatedClient();
}
/**
*/
protected function createAuthenticatedClient()
{
/** @var User $user */
$user = $this->em
->getRepository('Acme\AppBundle\Entity\User')
->findOneBy([], ['id' => DESC]; // Fetch the last created
// ...
return $client;
}
这对你的装置(它们更性感)来说是一个遗憾,但我不认为有任何方法可以将你的装置作为一个真正的入口,因为你无法与测试过的控制器进行更多的交互
另一种方法是创建对登录端点的请求,但这会更加糟糕。你说得对,@adsc也是。我接受他的答案的原因是因为它是提前一天做出的,解决了我的问题,即使你更好。抱歉,没问题@DevAntoine。我不太明白美国存托股的做法。您是否通过获取真实用户(而不是设备)来解决这个问题?是的,我正在使用客户机的容器获取从设备加载的用户。
$em = $client->getContainer()->get('doctrine')->getManager();
$em->merge($user);
/** @var EntityManager */
private $em;
/**
*/
public function setUp()
{
$client = static::createClient();
$this->em = $client->getKernel()
->getContainer()
->get('doctrine');
$this->authClient = $this->createAuthenticatedClient();
}
/**
*/
protected function createAuthenticatedClient()
{
/** @var User $user */
$user = $this->em
->getRepository('Acme\AppBundle\Entity\User')
->findOneBy([], ['id' => DESC]; // Fetch the last created
// ...
return $client;
}