如何使用Symfony 2获取当前登录用户的单元测试?

时间:2015-01-05 15:37:09

标签: php symfony phpunit unit-testing

我有这个单元测试:

class ProjectControllerTest extends WebTestCase
{

    private $client = null;
    private $projectName = null;

    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $em;

    public function setUp()
    {
        $kernel = static::createKernel();
        $kernel->boot();
        $this->client = $this->createAuthorizeClient($kernel);
        $this->em = $kernel->getContainer()->get('doctrine.orm.entity_manager');
    }

    public function testProjectNameEdition()
    {
        $project = new Project();
        $project
            ->setName(uniqid())
            ->setComment('test')
        ;
        $this->em->persist($project);
        $this->em->flush();

        $crawler = $this->client->request('GET', '/project/' . $project->getId() . '/edit');
        $form = $crawler->selectButton('codex_gui_project_submit')->form();
        $form['codex_gui_project[name]'] = $this->projectName . '1';
        $this->client->submit($form);

        $editProject = $this->em->getRepository('DatawordsCodexGuiBundle:Project')->findOneByName($oldProjectName . '1');
        $this->assertEquals($this->projectName . '1', $editProject->getName());
    }

    public function createAuthorizeClient($kernel)
    {
        $client = static::createClient();
        $container = $kernel->getContainer();
        $session = $container->get('session');
        $user = $kernel
            ->getContainer()->get('doctrine')
            ->getRepository('DatawordsCodexCoreBundle:User')
            ->findOneByUsername('Nico')
        ;
        $token = new UsernamePasswordToken($user, $user->getUserName(), 'main', $user->getRoles());

        $session->set('_security_main', serialize($token));
        $session->save();
        $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));

        return $client;
    }

}

然后当新实体持久化时,当前用户进入 ProjectListenner

class ProjectListener
{

    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * Prepersist a creation of project
     *
     * @param \Doctrine\ORM\Event\LifecycleEventArgs $args
     */
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Project) {
            // Save the user and the created date
            $usr = $this->container->get('security.context')->getToken()->getUser();
            $entity->setCreated(new \DateTime());
            $entity->setCreator($usr);
    }
}

运行测试时发生了错误

  

... PHP致命错误:在非对象中调用成员函数getUser()   /var/www/codex_gui/vendor/acme/foo/Acme/foo/fooBundle/Listener/ProjectListener.php   第32行

1 个答案:

答案 0 :(得分:1)

您在创建用户和登录用户方面存在一些错误。我不知道您为什么要进行这么多static::次调用,但您只应该这样做才能创建客户端。例如:

private $container;

public function setUp()
{
    $this->client = static::createClient();
    $this->container = $this->client->getContainer();
    $this->em = $this->container->get('doctrine.orm.entity_manager');

    $this->createAuthorizeClient();
}

您无需将$this->client传递给createAuthorizeClient()功能。它看起来应该更像

public function createAuthorizeClient()
{
    $session = $this->container->get('session');
    $user = $this->em->getRepository('AcmeFooBundle:User')
        ->findOneByUsername('Nico');

    // rest of the class here
}

可能还有其他问题,但这只是您可以做的基本事情。查看http://symfony.com/doc/current/cookbook/testing/simulating_authentication.html以及他们如何为其功能测试创建用户。