2016-07-26 36 views
0

这是我的问题,我添加来自功能测试控制器的会话变量,他们不会弹出测试目标的行动。 。Symfony2功能测试和会话持久性

我做了一个登录方法和使用cookbook advice登录我调整了一点,让2个帐户登录:admin和超级管理员

/** 
    * @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); 

我的设置()方法做到这一点:

/** 
    * {@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(); 
    } 

你可以看到我设置了认证的会话变量。当我从测试操作转储会话变量时它们显示正确,但是如果我添加currentSite会话变量,它似乎不会持续。当我使用客户端提供的测试容器时,应该传递它不应该吗?

PS:根据this other question,我也重写了Client类。

我在主题上发现了很多帖子,但都没有提供任何工作解决方案(this one,this onethat one)。 我也发现这个cookbook article

更新:感谢Alex Blex的评论,我在这里澄清我的问题的一些部分。

  • 设置()和login()是一个自定义WebTestCase类的两个部分,在这里通过嵌入我的应用程序需要的特异性
  • 我主要工具(如翻译...)是设置会话在PARAMS测试控制器和检索那些在测试动作中的会话参数

回答

0

这是不是很清楚你正在测试什么,你的期望,以及它失败的地方。添加实际测试是有意义的。为什么在你的测试中需要容器,翻译等?

会议没有什么特别的需要。考虑这个例子控制器,它在会议上仍然存在“测试”的价值,并增加其连续通话:

/** 
* @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()); 
} 

您的应用程序逻辑可能的方式较为复杂,但测试应该保持几乎相同 - 第一次调用登录,第二次调用以声明响应包含登录用户独有的东西。

UPDATE

在功能测试内部实现播放应该避免尽可能,然而,可能对某些边缘的情况下,例如基本以简化测试场景。

下面的示例测试通过从测试场景中设置特定的值到会话变量相同的控制器,并检查值由应用返回:

/** 
* @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()); 
} 
+0

感谢您的答复。我会澄清我的问题。我在帖子中的主要观点是找出为什么测试控制器中的session var initialize在测试操作中消失的原因。我还发现了一个我将尽快发布的解决方案。 – nbonniot

+0

够公平了,我已经更新了答案。仍然不相信你需要所有这些设置混乱。 –