30

我试图避免使用我的session[:referred_by],并想使用request.referrer. 但是,我的 RSpec 测试失败,因为TestRequest不存储request.referrer

因此,我必须执行以下操作才能使 Rspec 测试正常工作。有没有办法让它变得更好:

referrer = request.referrer ? request.referrer : '/'
redirect_to referrer, :alert => error_message
4

7 回答 7

47

ActionDispatch::TestRequest延伸ActionDispatch::Request那个延伸Rack::Request

方法定义如下

def referer
  @env['HTTP_REFERER']
end
alias referrer referer

据我记得,您可以使用request.env. 这意味着,应该可以设置类似

request.env['HTTP_REFERER'] = 'http://example.com'

当然,这取决于您使用的 RSpec 示例组的类型。

于 2012-09-25T22:47:58.970 回答
29

模拟它:

specify 'foo' do
  controller.request.should_receive(:referer).and_return('http://example.com')
  # get whatever
end

或者,如果您不在乎它是否没有被调用,请将其存根:

controller.request.stub referer: 'http://example.com'
于 2012-09-25T22:11:21.360 回答
15

在 Rails 5 上,公认的解决方案似乎不再适用,但正如Simone Carlettirequest.env['HTTP_REFERER']建议的那样,直接设置是有效的。

于 2017-07-03T09:04:57.950 回答
7

Rails 5.2+ & RSpec 3.8+ 的解决方案

get :endpoint, params: {}, headers: { 'HTTP_REFERER' => 'stackoverflow.com' }
于 2019-07-06T05:47:35.720 回答
2

对于 Rails4/Rspec3,在请求规范中,在request您进行 http 调用之前不可用。但是您可以通过执行以下操作来分配 request.referer:

get '/posts', {}, { referer: 'http://example.com' }
于 2018-08-28T01:18:48.883 回答
1

这也适用于控制器规格:

controller.request.headers.merge({ 'HTTP_REFERER': 'https://stackoverflow.com/' })
get(:endpoint)
于 2020-03-18T19:20:04.837 回答
0

对于其他在谷歌上搜索的人,您还可以像这样在帮助规范中存根请求:

allow(view).to receive_message_chain(:request, :referrer).and_return("http://example.com")
于 2017-08-11T21:19:19.007 回答