Symfony会话和phpunit麻烦

时间:2017-06-23 11:31:51

标签: php symfony phpunit

我的控制器中有这样的代码:

/**
 * @param Request $request
 * @param $verifiedResponse

 * @Route(...)

 * @return mixed
 */
public function someAction(Request $request)
{
    $session = $request->getSession();
    $session->set('key', mt_rand(0, 999));

    if ($request->get('key') === $session->get('key')) {
       return true;
    } else {
       return $session->get('key');
    }
    throw $this->createAccessDeniedException();
}

这是我的2个单元测试:

public function testSomeActionFirst()
{
   $client = static::createClient();
   $client->request('POST', $this->generateRoute('my_route'));
   return $client->getResponse()->getContent();
}

public function testSomeActionSecond($key)
{
   $client = static::createClient();
   $client->request('POST', $this->generateRoute('my_route'), [], [
       'key' => $key
   ]);
   $this->assertTrue($client->getResponse()->isOk()
}

第二次测试总是失败,因为响应代码是403,因为会话不会在请求之间保存。我怎么解决它?

1 个答案:

答案 0 :(得分:0)

每种测试方法都假设在隔离中运行。否则,您将遇到难以调试问题,因为一个测试会影响其他测试。单次测试失败会导致其他测试失败。这样的测试套件会给你很少的价值,因为失败的测试不会告诉你出了什么问题。 您可能一开始并不认识到这是一个问题,但维护这样的测试套件很快就会变得非常困难。

因此,您应该能够单独运行每项测试

您还应该能够以任何顺序运行测试

您在测试中使用的Web客户端已遵循这些规则,并在每个测试方法运行之前重置。尽管introduce test dependencies技术上可行,但即使采用这种方法,客户端也会被重置。这是件好事!

如果需要在每个测试用例中执行一些常见操作,请创建将封装(并命名!)该行为的辅助方法。例如:

class MyTest extends WebTestCase
{
    private $client;

    protected function setUp()
    {
        parent::setUp();
        $this->client = static::createClient();
    }

    public function testSomeActionSecond()
    {
       $key = $this->requestKey();

       $this->client->request(
           'POST',
           $this->generateRoute('my_route'), 
           [],
           ['key' => $key]
       );

       $this->assertTrue($this->client->getResponse()->isOk()
    }

    private function requestKey()
    {
       $this->client->request('POST', $this->generateRoute('my_route'));

       return $this->client->getResponse()->getContent();
    }
}