使用Minitest跳过Pundit授权

时间:2017-03-12 04:38:14

标签: ruby-on-rails devise minitest pundit

我使用以下方法为Pundit设置测试没有问题:

https://github.com/ksimmons/policy-assertions

在我的情况下,我的Pundit / Devise系统补充了注册类型系统以添加角色等。

当我测试我的控制器时,我想完全跳过整个Devise / Pundit系统,只关注控制器逻辑,而不是看我将在我的策略测试中处理的授权。

我看起来像这样(http://www.colorfultyping.com/disabling-devise-for-rails-integration-testing/#comment-4718),但我无法让它发挥作用。

1 个答案:

答案 0 :(得分:0)

为了跳过控制器中的Pundit授权,您需要存根 超出政策类' new方法返回占位符/模拟对象 以true响应正在测试的操作中的操作策略; 例如对于FooController我的FooPolicy会返回一个新的实例 在true内调用其操作政策index?时返回index 控制器动作。

对于Minitest,它看起来像这样

# - Minitest -
foo_policy = MiniTest::Mock.new
foo_policy.expect :index?, true

FooPolicy.stub :new, foo_policy do
  # your controller action test
end

您将创建一个模拟对象,该对象将履行Policy的新实例的角色 Controller操作中的对象,如果是策略,则返回该模拟对象 在测试期间,在其块的范围内调用new方法。

如果您使用Mocha,我相信以下内容也可以达到相同的效果 如上所述,但无需在其块内具体确定测试组合。

# - Mocha -
foo_policy = mock("foo_policy")
foo_policy.expects(:index?).returns(true)

FooPolicy.any_instance.stubs(:new).returns(foo_policy)

此外,您可以使用mock = Object.new和存根实现类似的模拟对象 定义mock内联方法的方法,如def mock.index?。这个 也适用于现有的类,因为Ruby允许您重新声明方法 对于像def FooPolicy.new这样的内联类,并且仅在内联中存在 测试范围。知道这一点,我们可以def FooPolicy.new并返回 我们的mock如下所示

# - Without a Test-framework -
foo_policy = Object.new # create a mock / double
def foo_policy.index?; true; end # stub a method

def FooPolicy.new # stub Policyclass to return double with stubbed method
  foo_policy = Object.new
  def foo_policy.index?; true; end
  foo_policy
end

为了完整起见,我使用RSpec并使用以下内容来删除我的Pundit 我的控制器操作中的政策

# - Rspec -
foo_policy = instance_double("policy", index?: true)
allow(FooPolicy).to receive(:new).and_return(foo_policy)

至于Devise,我使用以下支持测试助手,只包含它们 在测试之前需要用户sign_in的控制器和请求测试:

module DeviseRequestSpecHelpers
  include Warden::Test::Helpers

  def sign_in(resource_or_scope, resource = nil)
    resource ||= resource_or_scope
    scope = Devise::Mapping.find_scope!(resource_or_scope)
    login_as(resource, scope: scope)
  end

  def sign_out(resource_or_scope)
    scope = Devise::Mapping.find_scope!(resource_or_scope)
    logout(scope)
  end
end

请参阅Module: Warden::Test::Helpers — Documentation for hassox/warden (master) 有关Warden::Test::Helpers模块

的更多信息

这是因为Warden在Devise中使用其测试助手。 包含此Warden::Test::Helpers模块会将Warden切换到其中 test_mode!及其login_as方法会将您的user对象设置为 current_user用于测试使用Devise进行测试 应用

参考文献: