Модульный тест Symfony2

Я пытаюсь использовать Mockery для модульного тестирования моих функций sf2. Мучаюсь с первой попытки.

Сначала попробуйте протестировать класс, который использует контекст безопасности:

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);
}

При запуске модульного теста я получаю сообщение об ошибке:

набор тестовSecurityContext

Mockery\Exception: метод isGranted помечен как окончательный, и невозможно создать фиктивный объект с таким определенным методом. Вместо этого вы должны передать экземпляр этого объекта в Mockery, чтобы создать частичный макет.

Поэтому я соответствующим образом меняю свою тестовую функцию:

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

Теперь я получаю эту ошибку:

набор тестовSecurityContext

ErrorException: Catchable Fatal Error: Аргумент 1, переданный в Symfony\Component\Security\Core\SecurityContext::__construct(), должен реализовать интерфейс Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface, не указан, вызывается в ..MenuBuilderTest.php в строке 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 ... */

}

И получаю другую ошибку:

набор тестовSecurityContext

ErrorException: Catchable Fatal Error: Аргумент 2, переданный в Symfony\Component\Security\Core\SecurityContext::__construct(), должен реализовывать интерфейс Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface, не указан, вызван в ...\MenuBuilderTest.php в строке 94 и определено в ...\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);
}

И это все еще не в порядке, поскольку я получаю эту ошибку:

набор тестовSecurityContext

ErrorException: Catchable Fatal Error: Аргумент 1, переданный в Atos\Worldline\Fm\Integration\Ucs\EventFlowAnalyser\Menu\MenuBuilder::setSecurityContext(), должен быть экземпляром Symfony\Component\Security\Core\SecurityContext, экземпляр Mockery_50c5c1e0e68d2 задан, вызывается в ..\MenuBuilderTest.php в строке 106 и определяется в ..\MenuBuilder.php в строке 140

Я был бы очень признателен за помощь, прежде чем я закончу тест на 100 строк, чтобы проверить функцию из 8 строк...


person Alexandre Mélard    schedule 10.12.2012    source источник


Ответы (1)


Вместо того, чтобы издеваться над экземпляром, перейдите к интерфейсу, который он реализует. Он почти всегда работает лучше, и почти все в 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);
}
person Louis-Philippe Huberdeau    schedule 10.12.2012