【问题标题】:Rails: Testing authorization (Pundit) with RSpecRails:使用 RSpec 测试授权 (Pundit)
【发布时间】:2017-11-03 01:49:49
【问题描述】:

我想用 RSpec 彻底测试 Rails 应用程序授权设置 (Pundit)。

  1. Pundit docsother respectful sources 建议为 Pundit 策略类编写单元测试。这些测试是测试行为(好)还是测试实现细节(坏)?

  2. 如果我们实际上是在测试行为,如果我们最终从 Pundit 切换到另一个授权 gem 或滚动我们自己的授权,我们的测试难道不应该通过吗?

  3. 假设对 authorize 方法的调用意外地从控制器操作中删除,使其开放供公众访问。 Pundit 政策测试将继续通过。如果我们没有其他测试涵盖这一点,我们的测试套件可能全是绿色的,而我们的应用程序存在严重的安全漏洞。我们怎样才能避免这种情况?也许为 Pundit 控制器类编写单元测试,为控制器单独单元测试并在控制器测试中模拟 authorize 方法以确保它们被调用?

编辑:再想一想,我对类的实现细节和公共 API 之间的区别有一个判断失误。调用特定的公共方法、传递特定的参数并期望特定的返回值是对任何类进行单元测试(和使用)的要求。请忽略第 3 项 我原来的论点是无效的。

  1. 代替测试 Pundit 策略类,我们可以编写控制器或请求规范,以不同的用户角色登录,调用控制器操作并断言是授予还是拒绝访问。在这种方法中,即使我们切换到另一个授权 gem,测试也会继续通过。此外,如果不调用 authorize 方法,它们也会失败。但是,这些将是集成测试,并且应该比单元测试 Pundit 策略类慢。这是否是测试授权设置的更好方法?

提前致谢。

【问题讨论】:

    标签: ruby-on-rails testing rspec tdd pundit


    【解决方案1】:

    1) Pundit 文档和其他受人尊敬的来源)建议编写单元 测试 Pundit 策略类。那些测试是测试行为吗 (好)还是实施细节(坏)?

    一个好的策略规范是测试系统组件的行为。并非所有不测试整个系统的规范都是邪恶的。它是关于测试是什么 - 而不是它是如何做到的

    您可以将此与测试服务对象或任何其他组件进行比较。

    我发现策略规范是测试授权行为的一种非常简洁和准确的方法,无需额外的抽象层(HTTP、应用程序状态......)。这很像模型规范如何更好地测试验证边缘案例,而不是拖着 Capybara。

    2) 如果我们实际上是在测试行为,如果我们最终从 Pundit 切换到另一个授权,我们的测试是否仍然可以通过? gem 还是滚动我们自己的授权?

    是的 - 但这几乎可以针对系统中的任何组件进行争论。 您的更高级别规格(请求和功能)应该仍然通过(这也包括控制器正确集成 Pundit)。

    3) 假设对授权方法的调用被意外删除 一个控制器动作,让它对公众开放。权威政策 测试将继续通过。如果我们没有其他测试涵盖这一点,我们的 测试套件可能都是绿色的,而我们的应用程序具有严格的安全性 脆弱性。我们怎样才能避免这种情况?也许为 Pundit 控制器类,控制器的单独单元测试和 在控制器测试中模拟授权方法以确保它们是 叫什么?

    Controller tests are depreachiated in Rails 5。使用请求或功能规范,而不是窥探内部。

    您应该有请求/功能规范,以确保用户无法执行他们无权执行的操作。例如,在 API 的请求规范中,您将检查响应代码是否为 Unauthorised (401)。如果您偏执,您还可以检查是否未执行任何更改。

    对于功能规范,您测试用户是否被重定向或通知他们无法执行该操作。

    再次测试是什么 - 而不是它是如何做到的

    由于这是相当重复的,您可以使用shared examples 将其擦干。

    4) 我们可以编写控制器,而不是测试 Pundit 策略类 或请求使用不同用户角色登录的规范,调用 控制器操作并断言访问是被授予还是被拒绝。在 这种方法,即使我们切换到 另一个授权宝石。此外,如果授权,他们将失败 方法没有被调用。但是,这些将是集成测试和 应该比单元测试 Pundit 策略类慢。能不能 是测试授权设置的更好方法吗?

    再一次,这里的选择不是二元的。两种类型的测试都提供价值。您可以通过单独的集成测试来获得,但要涵盖所有可能的情况和边缘情况很难且缓慢。

    【讨论】:

      猜你喜欢
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多