通过 RSpec 发送自定义标头
Posted
技术标签:
【中文标题】通过 RSpec 发送自定义标头【英文标题】:Sending custom headers through RSpec 【发布时间】:2013-08-28 14:19:50 【问题描述】:鉴于我的 API 使用者需要像这样发送客户 HTTP 标头:
# curl -H 'X-SomeHeader: 123' http://127.0.0.1:3000/api/api_call.json
然后我可以像这样在 before_filter 方法中读取此标头:
# app/controllers/api_controller.rb
class ApiController < ApplicationController
before_filter :log_request
private
def log_request
logger.debug "Header: #request.env['HTTP_X_SOMEHEADER']"
...
end
end
到目前为止很棒。现在我想使用 RSpec 进行测试,因为行为发生了变化:
# spec/controllers/api_controller_spec.rb
describe ApiController do
it "should process the header" do
@request.env['HTTP_X_SOMEHEADER'] = '123'
get :api_call
...
end
end
但是,在 ApiController 中接收到的request
将无法找到标头变量。
尝试使用带有 HTTP_ACCEPT_LANGUAGE 标头的 same code
时,它会起作用。自定义标头是否在某处过滤?
PS:网络上的一些示例使用request
而不是@request
。虽然我不确定在当前的 Rails 3.2/RSpec 2.14 组合中哪一个是正确的 - 这两种方法都不会触发正确的行为,但两者都适用于 HTTP_ACCEPT_LANGUAGE
。
【问题讨论】:
【参考方案1】:你可以直接在get
中定义。
get :api_call, nil, 'HTTP_FOO'=>'BAR'
我刚刚验证它可以在控制台中运行。
【讨论】:
对不起 - 你的答案就在我测试的时候出现了。请查看更新。谢谢。 再次感谢 - 我也试过了,但它对我不起作用。您是否已在 RSpec 控制器规范中成功测试了这一点? 我用这个头请求,然后我请求request.env
,这个头就出现了。 get
是 Rails 的 ActionDispatch::Integration::RequestHelpers
方法,而不是 Rspec。我没有在 Rspec 中这样做,但我 100% 确定它会起作用。
如前所述,我也添加了@request.env['HTTP_ACCEPT_LANGUAGE'] = 'en'
- 这很有效,并且可以使用request.env
读取变量。似乎有一个我不知道的过滤器。
我认为@BillyChan 是正确的问题是你不应该从request.env
读取标题,但从request.headers
api.rubyonrails.org/classes/ActionDispatch/… 自定义标题不会包含在request.env
github.com/rails/rails/blob/…
【参考方案2】:
好吧,对人们来说可能为时已晚,但只是排队:
it 'should get profile when authorized' do
user = FactoryGirl.create :user
request.headers[EMAIL_TOKEN] = user.email
request.headers[AUTH_TOKEN] = user.authentication_token
get :profile
response.should be success
end
只需使用适当的设置调用 request.headers。
【讨论】:
@request 对我来说是零 抱歉,已修复,应该没有@request
也为零
确保你的控制器规范文件下有“render_views”
对我不起作用。我试过@request.headers['X-DeviceId'] = 'fd243cde'`(也是request
...)。标头不会到达。这是在控制器规范中吗?你能读取 before_filter 中的值吗?【参考方案3】:
RSpec 请求规范 changed in Rails 5 以便现在必须使用键值哈希参数定义自定义 headers
和 params
。例如:
Rails 4 之前:
it "creates a Widget and redirects to the Widget's page" do
headers = "CONTENT_TYPE" => "application/json"
post "/widgets", ' "widget": "name":"My Widget" ', headers
expect(response).to redirect_to(assigns(:widget))
end
现在适用于 Rails 5:
it "creates a Widget and redirects to the Widget's page" do
headers = "CONTENT_TYPE" => "application/json"
post "/widgets", :params => ' "widget": "name":"My Widget" ', :headers => headers
expect(response).to redirect_to(assigns(:widget))
end
【讨论】:
我的结果 - 这只是在参数中添加了一个“标题”部分。服务器接收到的标头始终是 "HTTPS"=>"off", "HTTP_HOST"=>"example.org", "HTTP_COOKIE"=>"" - 这些标头的定义位置或更改方法是未知。以上是关于通过 RSpec 发送自定义标头的主要内容,如果未能解决你的问题,请参考以下文章