Bru*_*cca 5 testing tdd rspec ruby-on-rails pundit
我想使用 RSpec 彻底测试 Rails 应用程序授权设置 (Pundit)。
Pundit 文档和其他值得尊敬的来源建议为 Pundit 策略类编写单元测试。这些测试是测试行为(好)还是实施细节(坏)?
如果我们实际上正在测试行为,那么如果我们最终从 Pundit 切换到另一个授权 gem 或滚动我们自己的授权,我们的测试难道不应该仍然通过吗?
假设对该authorize方法的调用被意外地从控制器操作中删除,使其开放供公共访问。权威人士的政策测试将不断通过。如果我们没有其他测试涵盖这一点,我们的测试套件可能都是绿色的,而我们的应用程序存在严重的安全漏洞。我们怎样才能避免这种情况呢?也许为 Pundit 控制器类编写单元测试,为控制器单独进行单元测试并模拟authorize控制器测试中的方法以确保调用它们?
编辑:再想一想,我对类的实现细节和公共 API 之间的差异做出了判断。调用特定的公共方法、传递特定的参数并期望特定的返回值是对任何类进行单元测试(和使用)的要求。请忽略第3项,因为我原来的论点是无效的。
authorize不调用该方法,它们也会失败。然而,这些将是集成测试,并且应该比单元测试 Pundit 策略类慢。这是否是测试授权设置的更好方法?提前致谢。
1) Pundit 文档和其他值得尊敬的来源)建议为 Pundit 策略类编写单元测试。这些测试是测试行为(好)还是实施细节(坏)?
一个好的策略规范是测试系统组件的行为。并非每个不测试整个系统的规范都是邪恶的。而是测试它做什么,而不是测试它如何做。
您可以将其与测试服务对象或任何其他组件进行比较。
我发现策略规范是一种非常简洁且准确的测试授权行为的方法,无需额外的抽象层(HTTP、应用程序状态...)。这很像模型规范如何更好地测试验证边缘情况,而不是沿着水豚拖动。
2)如果我们实际上正在测试行为,那么如果我们最终从 Pundit 切换到另一个授权 gem 或滚动我们自己的授权,我们的测试难道不应该仍然通过吗?
是的 - 但这对于系统中的任何组件来说几乎都是有争议的。您的更高级别规格(请求和功能)仍应通过(还涵盖控制器正确集成 Pundit)。
3) 假设对授权方法的调用被意外地从控制器操作中删除,使其开放供公共访问。权威人士的政策测试将不断通过。如果我们没有其他测试涵盖这一点,我们的测试套件可能都是绿色的,而我们的应用程序存在严重的安全漏洞。我们怎样才能避免这种情况呢?也许为 Pundit 控制器类编写单元测试,为控制器单独进行单元测试,并在控制器测试中模拟授权方法以确保调用它们?
Rails 5 中不再提倡控制器测试。使用请求或功能规范,而不是窥探内部结构。
您应该制定请求/功能规范,以确保用户无法执行他们无权执行的操作。例如,在 API 的请求规范中,您将检查响应代码是否为Unauthorised (401). 如果您偏执的话,您还可以检查是否没有执行任何更改。
对于功能规范,您测试用户是否被重定向或通知他们无法执行该操作。
再次测试它是什么——而不是它是如何做的。
由于这是相当重复的,您可以使用共享示例来总结它。
4) 我们可以编写使用不同用户角色登录的控制器或请求规范,调用控制器操作并断言是否授予或拒绝访问,而不是测试 Pundit 策略类。在这种方法中,即使我们切换到另一个授权 gem,测试也会继续通过。此外,如果不调用授权方法,它们也会失败。然而,这些将是集成测试,并且应该比单元测试 Pundit 策略类慢。这是否是测试授权设置的更好方法?
同样,这里的选择不是二元的。两种类型的测试都具有价值。您可以仅通过集成测试来完成,但是覆盖每种可能的情况和边缘情况很难而且很慢。