在Rails/RSpec请求测试中模拟非本地请求

3
我希望您能够封锁所有非本地请求者对应用程序的访问(在实践中,我的应用程序功能更为复杂,但是找到如何做到这一点将解决我的具体问题)。我该如何使用RSpec中的请求测试来测试这个功能?
spec/requests/gatekeeper_spec.rb中。
describe "A local request to the site root" do
  before :each do
    get root_path
  end
  it "should not allow access" do
    response.status.should be(401)
  end
end

describe "An external (terminology?) request to the site root" do
  before :all do
    # TODO: make request remote
  end
  before :each do
    get root_path
  end
  it "should allow access" do
    response.status.should be(200)
  end
end

我应该如何实现# TODO行?我已经研究了mocks,并认为伪造request.remote_ip可能是适当的,但我不确定这样的mock具体是如何实现的。


我不熟悉Ruby on Rails,但是“it "should [not] allow access"是否应该改为“如果...”? - Hello71
@Hello71:别担心。RSpec很时髦;it是正确的。这是Ruby世界中整个可读性趋势的一部分。 - Steven
3个回答

2

如果我理解正确,测试请求的远程地址为“0.0.0.0”,因此它们通常被视为远程请求,您需要存根本地请求而不是反过来。

我认为这对于控制器规范应该可以工作 - 不确定请求规范是否适用:

request.stub(:local?) { true }

在请求通过get进行时,请求对象似乎不存在。我认为扩展该函数是解决这个难题的最佳方法。 - Steven
2
哦,看起来请求规范有所不同。您也可以尝试get root_path, nil, "REMOTE_ADDR" => "127.0.0.1"来模拟本地主机。 - zetetic
存根的想法很好,我在我的控制器规范中有效地使用了它。我将“访问检查器”实现为before_filter,并将相应的过滤器存根为仅返回true而不是重定向。控制器规范允许我通过本地变量controller访问控制器。至于请求规范,我无法使其正常工作,但该函数已经更改,因此希望至少在Rails指南填补该细节之前忽略这个差距。 - Steven

2

未经测试,但应该适用于Rails 2.3.x和3.0:

before :each do
  Rails::Initializer.run do |config|
    config.action_controller.consider_all_requests_local = false
  end
end

after :each do
  Rails::Initializer.run do |config|
    config.action_controller.consider_all_requests_local = true
  end
end

1
在 Rails 4 中,您可以使用以下代码实现:

RSpec.configure do |config|
  config.before(:each, allow_rescue: true) do
    Rails.application.config.action_dispatch.stub(:show_exceptions) { true }
    Rails.application.config.stub(:consider_all_requests_local) { false }
  end
end

然后在你的测试文件中:

describe "A test" do
  it "renders custom error pages", :allow_rescue => true do
    # ...
  end
end

这里的:allow_rescue名称来自于Rails 3中存在的ActionController::Base.allow_rescue配置,因此在那里,RSpec的配置将是:
RSpec.configure do |config|
  config.before(:each, allow_rescue: true) do
    ActionController::Base.stub(:allow_rescue) { true }
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接