覆盖action_controller.allow_forgery_protection以进行特定集成测试

时间:2011-05-06 23:11:07

标签: ruby-on-rails security ruby-on-rails-3 testing integration-testing

我有一个在我的基本应用程序控制器中使用protect_from_forgery的rails3应用程序。我正在使用ActionDispatch::IntegrationTest并希望确保在某些集成测试期间存在真实性令牌。

我不希望执行帖子的每个功能测试都必须传递authenticity_token,因此我的test.rb文件指定:

  config.action_controller.allow_forgery_protection    = false

正如rails文档所暗示的那样。

但是,对于集成测试,我希望确保我的表单正确发送真实性令牌。如果不在config/environments/test.rb

中全局更改设置,我找不到任何方法

如果我的所有表单都是用form_for生成的,我会满足于相信rails会处理这个,但是我使用ExtJS并且有许多需要手动指定的ExtJS表单,所以我真的应该测试一下管道工作都在工作。

3 个答案:

答案 0 :(得分:9)

您只需更改集成测试设置中的值:

require 'test_helper'

class MyCrunchyIntegrationTest < ActionController::IntegrationTest
  fixtures :all

  def setup
    ActionController::Base.allow_forgery_protection = true
  end

  def teardown
    ActionController::Base.allow_forgery_protection = false
  end

  test "how awesome my application is" do
    # ...
  end
end

答案 1 :(得分:8)

辅助方法,可以暂时阻止块的伪造:

def with_forgery_protection
  orig = ActionController::Base.allow_forgery_protection
  begin
    ActionController::Base.allow_forgery_protection = true
    yield if block_given?
  ensure
    ActionController::Base.allow_forgery_protection = orig
  end
end

with_forgery_protection do
  # code in here will require csrf token
end

答案 2 :(得分:2)

这是@ gmcnaughton解决方案的RSpec版本。

这是spec_helper.rb

RSpec.configure do |config|
  config.around(:each, :with_csrf_protection) do |example|
    orig = ActionController::Base.allow_forgery_protection

    begin
      ActionController::Base.allow_forgery_protection = true
      example.run
    ensure
      ActionController::Base.allow_forgery_protection = orig
    end
  end
end

然后你写下测试:

it "foo", with_csrf_protection: true do
  # …
end

或者,取决于您的RSpec设置:

it "foo", :with_csrf_protection do
  # …
end