2016-02-23 4 views
3

Я хотел бы проверить способ с контролем доступа, например. метод предоставляется только с определенной ролью. Поэтому, я знаю два способа в Symfony:Проверка модуля Symfony Безопасность (ACL - Аннотация)

  1. @Security аннотации выше методы (SensioFrameworkExtraBundle) ИЛИ
  2. Вызывать authorization_checker explizit внутри моего метода

Когда речь идет о единичных испытаниях (для моего случая phppec, но я думаю, что поведение phpunit почти одинаково в этом случае), я бы хотел проверить, что только анонимные пользователи должны иметь возможность вызвать метод. С номером 2. он работает нормально. Вот мои настройки:

RegistrationHandlerSpec:

class RegistrationHandlerSpec extends ObjectBehavior 
{  
    function let(Container $container, AuthorizationCheckerInterface $auth) { 
    $container->get('security.authorization_checker')->willReturn($auth); 
    $this->setContainer($container); 
    } 

    function it_should_block_authenticated_users(AuthorizationCheckerInterface $auth) 
    { 
    $auth->isGranted("ROLE_USER")->willReturn(true); 
    $this->shouldThrow('Symfony\Component\Security\Core\Exception\AccessDeniedException')->during('process', array()); 
    } 
} 

И в RegistrationHandler, я следующий метод:

class RegistrationHandler 
{ 
    public function process() 
    { 
    $authorizationChecker = $this->get('security.authorization_checker'); 
    if ($authorizationChecker->isGranted('ROLE_USER')) { 
     throw new AccessDeniedException(); 
    } 
    // ... 
    } 
} 

Ну, этот подход работает отлично - но, как правило, я бы предпочел, используя 1. с аннотацией безопасности (Sensio FrameworkExtraBundle), и, следовательно, он не работает/я не знаю, почему не запускается исключение, когда оно записано в виде аннотации:

/** 
* @Security("!has_role('ROLE_USER')") 
*/ 
public function process() 
{ 
    // ... 
} 

Кто-нибудь знает, как заставить этот пример работать, используя первый подход с аннотацией @Security, которая является более читаемой и рекомендуемой для Symfony?

ответ

6

В обоих случаях вы тестируете поведение, предоставляемое сторонним кодом (инфраструктура Symfony). Следуя правилу , не издевайтесь над тем, что вы не являетесь владельцем, вместо написания модульного теста вы должны написать тест интеграции. В противном случае вы будете делать только предположения о том, как работает код без каких-либо доказательств, что он действительно работает таким образом.

В вашем случае ваш интеграционный тест может быть контрольным тестом. Вы вызываете URL-адрес с помощью веб-тестового клиента (предоставленного WebTestCase) и убедитесь, что в определенных условиях вы получаете ответ 401 или 403.

PHPSpec - это инструмент для единичного тестирования (a.k.a. инструмент для проектирования). Вам нужно написать интеграционные тесты с чем-то другим (например, PHPUnit). Я обычно, по крайней мере, три инструмента тестирования установлен в моем проекте:

  • PhpSpec для модульного тестирования
  • PHPUnit для интеграции тестирования
  • Behat для приемочных испытаний (форма интеграционного тестирования)
+0

Hi Якуб, спасибо за ваш ответ, теперь я больше разбираюсь в тестировании. Поэтому я бы использовал следующий порядок для разработки новой функции с помощью описанных вами инструментов: 1) жизненный цикл BDD (Behat, PHPSpec, Prodcode, Refactor) для «нормальных» классов и 2) Когда дело доходит до создания контроллера, я бы сначала создать очень маленький phpspec и более крупный интеграционный тест, потому что контроллеры не тестируются много, а функционально? Кроме того, что еще вы испытываете? Ответ на эти два вопроса должен полностью очистить мой разум и привести к щедрости. С уважением – user3746259

+1

Зависит, если вы хотите строить из «наружного» или «наизнанку». Большинство людей предпочитают снаружи. Вы начинаете с какого-либо приемочного теста (Behat или PHPUnit) или функционального теста (PHPUnit).По мере углубления вы будете писать модульные тесты для классов (PhpSpec или PHPUnit), отключаться от инфраструктуры и вводить интерфейсы для их издевательства. Осталось проверить реализации этих инфраструктурных интерфейсов. Вот тут и появляются интеграционные тесты. Вы также можете заменить реализации инфраструктуры инфраструктуры в своем принятии один раз более простым, чтобы сделать их быстрее. –

+0

Что касается контрольных контроллеров - зависит от того, как вы их обрабатываете, но большую часть времени да, вы бы покрыли их некоторыми интеграционными тестами (например, функциональными тестами). –

 Смежные вопросы

  • Нет связанных вопросов^_^