1

sf2 関数を単体テストするために Mockery を使用しようとしています。初めての試みで苦労しています。

まず、セキュリティ コンテキストを使用するクラスをテストしてみます。

public function setSecurityContext(SecurityContext $securityContext)
{
    $this->securityContext = $securityContext;
    try {
        $this->isLoggedIn = $securityContext->isGranted('IS_AUTHENTICATED_FULLY');
        $this->user = $securityContext->getToken()->getUser();
    } catch (\Exception $e) {
        $this->isLoggedIn = false;
        $this->user = $securityContext->getToken()->getUser();
    }
}

次のようなtestsetSecurityContext関数を作成します。

public function testsetSecurityContext()
{
    /* @var $securityContext SecurityContext */
    $securityContext = m::mock('Symfony\Component\Security\Core\SecurityContext');

    $securityContext->shouldReceive('isGranted')
    ->with('IS_AUTHENTICATED_FULLY')
    ->once()
    ->andReturn(true);

    $factory = m::mock('Knp\Menu\FactoryInterface');

    $menu = new MenuBuilder($factory);

    $menu->setSecurityContext($securityContext);
}

単体テストを実行すると、次のエラーが表示されます。

testsetSecurityContext

Mockery\Exception: メソッド isGranted は final とマークされており、そのようなメソッドが定義されたモック オブジェクトを生成することはできません。代わりに、このオブジェクトのインスタンスを Mockery に渡して、部分的なモックを作成する必要があります。

したがって、それに応じてテスト関数を変更します。

public function testsetSecurityContext()
{
    /* @var $securityContext SecurityContext */
    $securityContext = m::mock(new \Symfony\Component\Security\Core\SecurityContext());
    /* ... skipped ... */
}

今、私はそのエラーを受け取ります:

testsetSecurityContext

ErrorException: Catchable Fatal Error: Argument 1 passed to Symfony\Component\Security\Core\SecurityContext::__construct() must implement interface Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface , none given, called in ..MenuBuilderTest.php on行 91 および ..Symfony\Component\Security\Core\SecurityContext.php 行 41 で定義

したがって、コードを再度変更します。

public function testsetSecurityContext()
{

    $auth = m::mock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');

    /* @var $securityContext SecurityContext */
    $securityContext = m::mock(new \Symfony\Component\Security\Core\SecurityContext($auth));

    /* ... skipped ... */

}

そして、別のエラーが発生します:

testsetSecurityContext

ErrorException: Catchable Fatal Error: Argument 2 passed to Symfony\Component\Security\Core\SecurityContext::__construct() must implement interface Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface , none given, ...\MenuBuilderTest で呼び出されます. 94 行目の php で ...\Symfony\Component\Security\Core\SecurityContext.php 行 41 で定義されています

私は最終的に:

public function testsetSecurityContext()
{

    $am = m::mock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
    $adm = m::mock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');

    /* @var $securityContext SecurityContext */
    $securityContext = m::mock(new \Symfony\Component\Security\Core\SecurityContext($am, $adm));

    $securityContext->shouldReceive('isGranted')
    ->with('IS_AUTHENTICATED_FULLY')
    ->once()
    ->andReturn(true);

    $factory = m::mock('Knp\Menu\FactoryInterface');

    $menu = new MenuBuilder($factory);

    $menu->setSecurityContext($securityContext);
}

そして、私はそのエラーが発生するので、それはまだOKではありません:

testsetSecurityContext

ErrorException: Catchable Fatal Error: Atos\Worldline\Fm\Integration\Ucs\EventFlowAnalyser\Menu\MenuBuilder::setSecurityContext() に渡される引数 1 はSymfony\Component\Security\Core\SecurityContextのインスタンスである必要があり、与えられたMockery_50c5c1e0e68d2のインスタンスである必要があります。 ..\MenuBuilderTest.php の 106 行で呼び出され、..\MenuBuilder.php の 140 行で定義されています。

8行の機能をテストするために100行のテストを行う前に、本当に助けていただければ幸いです...

4

1 に答える 1

5

インスタンスをモックする代わりに、それが実装するインターフェースを探してください。Symfony2 のほぼすべてが適切に定義されたインターフェースを備えています。

MenuBuilder がカスタム クラスの場合は、実際の実装ではなくインターフェイスも使用する必要があります。

Symfony\Component\Security\Core\SecurityContextInterface

public function testsetSecurityContext()
{
    /* @var $securityContext SecurityContext */
    $securityContext = m::mock('Symfony\Component\Security\Core\SecurityContextInterface');

    $securityContext->shouldReceive('isGranted')
    ->with('IS_AUTHENTICATED_FULLY')
    ->once()
    ->andReturn(true);

    $factory = m::mock('Knp\Menu\FactoryInterface');

    $menu = new MenuBuilder($factory);

    $menu->setSecurityContext($securityContext);
}
于 2012-12-10T14:29:35.103 に答える