【问题标题】:Symfony unit test Security (ACL - Annotation)Symfony 单元测试安全性(ACL - 注释)
【发布时间】:2016-06-05 10:16:56
【问题描述】:

我想检查一个带有访问控制的方法,例如一个方法只被授予一个特定的角色。因此,我在 Symfony 中知道两种方式:

  1. 方法上方的@Security注解(SensioFrameworkExtraBundle)或
  2. 在我的方法中调用 authorization_checker explizit

当涉及到单元测试时(对于我的情况是 phpspec,但我认为 phpunit 的行为在这种情况下几乎相同),我想测试只有匿名用户才能调用方法。使用数字 2. ,它工作正常。这是我的设置:

注册处理程序规范:

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. with Security annotation (Sensio FrameworkExtraBundle),因此,它不起作用/我不知道为什么在编写为注释:

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

有谁知道如何通过使用带有@Security 注释的第一种方法来使这个示例工作,这种方法更易读,推荐symfony 的最佳实践?

【问题讨论】:

    标签: phpunit acl symfony phpspec


    【解决方案1】:

    在这两种情况下,您都在测试由第三方代码(Symfony 框架)提供的行为。遵循规则不要模拟你不拥有的东西,而不是编写单元测试,你应该编写集成测试。否则,您只会对代码的工作方式做出假设,而没有证据证明它确实以这种方式工作。

    在您的情况下,您的集成测试可能是控制器测试。您将使用 Web 测试客户端(由 WebTestCase 提供)调用 URL,并验证在某些情况下您是否收到 401 或 403 响应。

    PHPSpec 是一个单元测试工具(又名设计工具)。您需要使用其他东西(例如 PHPUnit)编写集成测试。我的项目中通常至少安装了三个测试工具:

    • 用于单元测试的 PhpSpec
    • 用于集成测试的 PHPUnit
    • Behat 用于验收测试(一种集成测试形式)

    【讨论】:

    • 嗨,Jakub,感谢您的回答,现在我对测试有了更多的了解。因此,我将使用以下顺序使用您描述的工具开发新功能:1)“普通”类的 BDD 生命周期(Behat、PHPSpec、Prodcode、Refactor)和 2)在创建控制器时,我会首先创建一个非常小的 phpspec 和一个更大的集成测试,因为控制器没有经过太多单元测试而是功能性的?此外,您还测试了哪些其他内容?回答这两个问题应该让我完全清醒,并会带来赏金。问候
    • 取决于您是喜欢从“外向内”还是“从内向外”构建。大多数人更喜欢由外而内。您从某种验收测试(Behat 或 PHPUnit)或功能测试(PHPUnit)开始。随着您的深入,您将为类(PhpSpec 或 PHPUnit)编写单元测试,从基础设施中解耦并引入接口来模拟它们。剩下的就是测试那些依赖于接口的基础设施的实现。这就是集成测试的用武之地。您还可以将验收中的基础架构实施替换为更简单的实施,以使其更快。
    • 至于测试控制器 - 取决于你如何对待它们,但大多数时候是的,你会用某种集成测试(如功能测试)来覆盖它们。
    • 你有一个很好的使用接口的链接吗?我知道他们做什么,但我很少使用它们。感谢您的想法!
    • 我没有想到任何链接。这是纯粹的OOD。这本书也许:amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258
    猜你喜欢
    • 2019-08-06
    • 2011-10-28
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 2017-11-03
    • 2019-06-04
    相关资源
    最近更新 更多