Rails:使用RSpec

时间:2017-06-01 19:25:51

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

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

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

  2. 如果我们实际测试行为,如果我们最终从Pundit切换到另一个授权gem或推出我们自己的授权,我们的测试是否仍然无法通过?

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

  4. 编辑:第二个想法,我对实施细节与课程的公共API之间的差异做出了判断。调用特定的公共方法,传递特定的参数并期望特定的返回值是单元测试(和使用)任何类的要求。请忽略第3项  我的原始论点无效。

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

1 个答案:

答案 0 :(得分:4)

  

1)Pundit文档和其他尊重的来源)建议写作单位   Pundit策略类的测试。这些测试是否测试行为   (好)或实施细节(坏)?

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

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

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

  

2)如果我们实际上正在测试行为,如果我们最终从Pundit切换到另一个授权,我们的测试不应该通过   宝石还是我们自己的授权?

是的 - 但对于系统中的任何组件,这几乎都可以争论。 您的更高级别规范(请求和功能)仍应通过(这也涵盖控制器正确集成Pundit)。

  

3)假设意外删除了对authorize方法的调用   控制器操作,将其打开以供公共访问。权威政策   测试将继续通过。如果我们没有其他测试,我们的   我们的应用程序具有严重的安全性,测试套件可能全部为绿色   漏洞。我们怎能避免这种情况?也许写单元测试   Pundit控制器类,控制器和单独的单元测试   在控制器测试中模拟授权方法以确保它们是   叫?

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

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

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

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

由于这是非常重复的,你可以使用shared examples来干掉它。

  

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

这里的选择再次不是二元的。两种类型的测试都提供了价值。你可以通过单独的集成测试来获得,但是它很难和很慢地覆盖每个可能的案例和边缘情况。