Symfony2功能测试和会话持久性 [英] Symfony2 functional test and session persistance

查看:255
本文介绍了Symfony2功能测试和会话持久性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的问题,我从功能测试控制器添加了会话变量,它们没有弹出测试所针对的操作.

Here is my problem, I add session variable from functional test controller and they don't popup on action targeted by test.

我制作了一种登录方法,并使用烹饪书建议登录.我进行了一些调整,以允许2个帐户登录:admin和superadmin

I made a login method and used cookbook advice to log in. I tuned it a bit to allow 2 accounts login : admin and superadmin

/**
     * @param $account string the account to log in with (authorized : superadmin and admin)
     */
    protected function logIn($account)
    {
        $this->session = $this->container->get('session');
        // Cookbook try
        // $this->session = new Session(new MockFileSessionStorage());
        $user = $this->em->getRepository('LCHUserBundle:User')->findOneByUsername($account);
        $firewall = 'admin_area';

        switch($account) {
            case self::SUPER_ADMIN_LOGIN:
                $token = new UsernamePasswordToken($user, $account, $firewall, array('ROLE_SUPER_ADMIN'));
                $this->client->setServerParameter("SERVER_NAME", SiteControllerTest::ROOT_SITE);
                $this->client->setServerParameter("HTTP_HOST", SiteControllerTest::ROOT_SITE);
                break;
            case self::ADMIN_LOGIN:
                $token = new UsernamePasswordToken($user, $account, $firewall, array('ROLE_ADMIN'));

                // Session var I wish to have on my controller action tested
                $this->session->set('currentSite', $this->em->getRepository('LCHMultisiteBundle:Site')->find(1));
                $this->session->save();

                // Use to force server canonical name for admin test
                $this->client->setServerParameter("SERVER_NAME", SiteControllerTest::ROOT_SITE);
                $this->client->setServerParameter("HTTP_HOST", SiteControllerTest::TEST_SITE);
                break;
            default:
                throw new UsernameNotFoundException('Username provided doesn\'t match any authorized account');
        }
        // Save user in session
        $this->session->set('_security_'.$firewall, serialize($token));
        $this->session->set('user', $user);
        $this->session->save();
        // $this->container->set('session', $this->session);

        $cookie = new Cookie($this->session->getName(), $this->session->getId());
        $this->client->getCookieJar()->set($cookie);

我的setUp()方法可以做到这一点:

My setUp() method does this :

/**
     * {@inheritDoc}
     */
    protected function setUp()
    {
        // Initiates client
        $this->client = static::createClient();

        $this->container = $this->client->getContainer();
        $this->application = new Application($this->client->getKernel());
        $this->application->setAutoExit(false);
        $this->translator = $this->container->get('translator');
        $this->em = $this->container
            ->get('doctrine')
            ->getManager();
    }

您可以看到我设置了用于身份验证的会话变量.当我从经过测试的操作中转储会话var时,它们会正确显示,但是如果我添加currentSite会话var,它似乎不会持久存在.当我使用客户端提供的测试容器时,应该将其传递通过吗?

You can see that I set session vars for authentication. They appear correctly when I dump session var from tested action, but if I add my currentSite session var, it seems not persisted. As I use the test container provided by client, it should be passed on shouldn't it?

PS:根据此内容,我还重写了Client类其他问题.

我找到了很多关于该主题的帖子,但没有一个提供任何可行的解决方案(这一篇食谱文章.

I found numerous posts on topic but none provide any working solution (this one, this one or that one). I also found this cookbook article.

更新::感谢Alex Blex的评论,在此我澄清了部分问题.

UPDATE : thanks to Alex Blex remark, I clarify here some parts of my question.

  • setUp()和logIn()都是自定义WebTestCase类的一部分,它们嵌入了我的应用程序特定性所需的工具(例如翻译器...)
  • 我在这里的主要观点是在测试控制器中设置会话参数,并在经过测试的操作中检索这些会话参数

推荐答案

尚不清楚您正在测试什么,期望什么以及失败的地方.添加实际测试将是有意义的.为什么在测试中根本不需要容器,翻译器等?

It is not quite clear what you are testing, what your expectations, and where it fails. It would make sense to add the actual test. Why do you need container, translator, etc in your tests at all?

会议不需要做任何特殊的事情.考虑这个示例控制器,该控制器在会话中保留'test'的值,并在连续调用时将其递增:

There is nothing special needs to be done for sessions. Consider this example controller, which persists value of 'test' in session and increments it on consecutive calls:

/**
 * @Route("/session")
 * @Method({"GET"})
 */
public function session()
{
    $session = $this->container->get('session');
    $current = $session->get('test', 0);
    $session->set('test', $current + 1);
    return new Response($current);
}

此测试通过:

/**
 * @test
 */
public function session_increments()
{
    $client = static::createClient();        
    $client->request("GET", '/session');
    $this->assertEquals('0', $client->getResponse()->getContent());
    $client->request("GET", '/session');
    $this->assertEquals('1', $client->getResponse()->getContent());
}

您的应用程序逻辑可能更复杂,但是测试应该保持几乎相同-第一次调用登录,第二次声明响应包含登录用户所独有的内容.

Your application logic may be way more complex, but the test should remain pretty much the same - first call to login, second call to assert the response contains something unique to the logged-in user.

更新

应尽可能避免在功能测试中使用内部实现,但是对于某些极端情况(例如测试)可能是必不可少的.简化测试方案.

Playing with internal implementation in functional tests should be avoided as much as possible, yet, may be essential for some edge-cases, e.g. to simplify testing scenarios.

以下示例通过在测试方案中为会话变量设置特定的值来测试同一控制器,并检查该值是否由应用返回:

The following example tests the same controller by setting specific value to the session variable from within the test scenario, and check the value is returned by the app:

/**
 * @test
 */
public function session_returns_value()
{
    $client = static::createClient();        
    $session = $client->getContainer()->get('session');
    $session->set('test', 12);
    $client->request("GET", '/session');
    $this->assertEquals('12', $client->getResponse()->getContent());
}

这篇关于Symfony2功能测试和会话持久性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆