5

セッションを実装するコントローラー メソッドでコントローラー ベースの単体テストを実行しようとすると、問題が発生します。

この場合、コントローラーメソッドは次のとおりです。

/**
 * @Route("/api/logout")
 */
public function logoutAction()
{
    $session = new Session();
    $session->clear();

    return $this->render('PassportApiBundle:Login:logout.html.twig');
}

そして機能テスト:

public function testLogout()
{
    $client = static::createClient();
    $crawler = $client->request('GET', '/api/logout');
    $this->assertTrue($client->getResponse()->isSuccessful());
}

生成されるエラー:

ヘッダーが既に送信されているため、セッションを開始できませんでした。(500内部サーバーエラー)

私は$this->app['session.test'] = true;テストに参加しようとしましたが、それでもうまくいきません。セッションを使用するコントローラーを単体テストするために、このような問題を解決しようとした人はいますか?

4

3 に答える 3

13

まず、コンテナからセッション オブジェクトを使用する必要があります。したがって、アクションは次のようになります。

/**
 * @Route("/api/logout")
 */
public function logoutAction()
{
    $session = $this->get('session');
    $session->clear();

    return $this->render('PassportApiBundle:Login:logout.html.twig');
}

そして、テストで「クライアントのコンテナ」にサービスを注入できます。そう:

public function testLogout()
{
    $sessionMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session')
        ->setMethods(array('clear'))
        ->disableOriginalConstructor()
        ->getMock();

    // example assertion:
    $sessionMock->expects($this->once())
        ->method('clear');

    $client = static::createClient();
    $container = $client->getContainer();
    $container->set('session', $sessionMock);

    $crawler = $client->request('GET', '/api/logout');
    $this->assertTrue($client->getResponse()->isSuccessful());
}

このコードを使用すると、セッション サービスで必要なことをすべて行うことができます。ただし、次の 2 つの点に注意する必要があります。

  • このモックは 1 つのリクエストに対してのみ設定されます (次のリクエストで使用する場合は、再度設定する必要があります)。これは、クライアントがカーネルを再起動し、各リクエストの間にコンテナーを再構築するためです。
  • Symfony 2.1 でのセッション処理は Symfony 2 とほとんど変わりません

編集:

主張を追加しました

于 2012-12-04T08:11:22.820 に答える
8

私の場合、設定するだけで十分でした

framework:
    session:
        storage_id: session.storage.mock_file

config_test.yml。YMMV、そして私が実際に何をしているのかはあまりわかりませんが、それは私にとってはうまくいきます.

于 2014-01-31T17:38:37.230 に答える
2

ここで、Cyprian の応答を完成させます。

Sven が説明しているように、symfony のドキュメントhttp://symfony.com/doc/2.3/components/http_foundation/session_testing.htmlを見ると、最初のコンストラクター引数として MockFileSessionStorage オブジェクトを使用してモック セッションをインスタンス化する必要があります。

使用する必要があります:

    use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;

コードは次のようになります。

    $sessionMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')
        ->setMethods(array('clear'))
        ->disableOriginalConstructor()
        ->setConstructorArgs(array(new MockFileSessionStorage()))
        ->getMock();
于 2013-12-30T14:59:53.883 に答える