在RSpec Rails中测试HTTPS(SSL)请求

时间:2011-07-22 03:12:01

标签: ruby-on-rails ssl https rspec ruby-on-rails-3.1

我想利用rails 3.1rc4中的force_ssl feature

class ApplicationController < ActionController::Base
  force_ssl
end

问题是这会破坏我现有的RSpec控制器规格的大部分/全部。例如,这失败了:

describe "GET 'index'" do
  it "renders the Start page" do
    get :index
    response.should render_template 'index'
  end
end

而不是呈现页面,响应是301重定向到https://test.host/

如何更改规格以模拟HTTPS GET / POST?

我是否必须手动更改每个测试或是否有更简单的方法? (我意识到我只能在生产中调用force_ssl,但这并不理想。真的,我应该测试force_ssl确实会在预期时重定向到https://。

4 个答案:

答案 0 :(得分:42)

要指示RSpec在控制器规范中发出SSL请求,请使用:

request.env['HTTPS'] = 'on'

在您的示例中,这看起来像:

describe "GET 'index'" do
  it "renders the Start page" do
    request.env['HTTPS'] = 'on'
    get :index
    response.should render_template 'index'
  end
end

答案 1 :(得分:2)

对于rspec 3语法,https://stackoverflow.com/a/28361428/1107433

get :index, protocol: 'https://'

上面的代码可能会有一些不同的版本。所以使用下面的代码:

get :index, protocol: :https

答案 2 :(得分:1)

作为参考,我当前正在运行Rails 5.2.4和RSpec 4。

最好的解决方案as given in this answer是从使用_path帮助程序变为使用_url帮助程序。

然后,您可以传递protocol参数以生成HTTPS URL:

get login_url(protocol: :https)

请注意,您无法将protocol传递给_path助手:

# NOTE: THIS IS WRONG. Doesn't work with the `_path` helper:
# get login_path(protocol: :https)

carp's comment above中提供的另一种选择是将"HTTPS"标头与虚假请求一起传递。

因此,如果您使用字符串/符号或_path帮助程序作为请求路径:

get login_path, headers: {"HTTPS" => "on"}

get '/login', headers: {"HTTPS" => "on"}

这是鲤鱼的完整评论:

对于实际的请求规范(与现在不建议使用的控制器规范相反),它的工作方式如下:get "/path", headers: { "HTTPS" => "on" }。 Rack :: Request将提取HTTPS标头,告诉所有内容以将请求视为SSL / TLS请求。

答案 3 :(得分:0)

如果您在应用程序的任何位置都需要SSL,则应在应用程序的任何位置使用它。然后,您只需使用rack-ssl gem并将Rack::SSL中间件添加到config/environments/production.rb。无需额外测试;没有破损;问题解决了。