如何在rspec请求规范中设置请求头?

139

在控制器规范中,我可以这样设置HTTP Accept头:

request.accept = "application/json"

但在请求规范中,“request”对象为空。那么我该怎么做呢?

我想设置http接受头为json的原因是这样我就可以做到这一点:

get '/my/path'

用这个代替

get '/my/path.json'
10个回答

139

3
我们需要使用 'HTTP_ACCEPT':`get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}`(说明:这是一个代码示例,意思是在发送HTTP请求时需要设置'HTTP_ACCEPT'头部信息为"application/json"。) - Matt Scilipoti
59
注意:这是用于集成测试的,类似于下面的评论,在rspec-rails的控制器测试中,您可以使用以下代码设置请求头:request.env["HTTP_ACCEPT"] = - Alex Soto
5
因为我很傻,所以碰到了一个小问题:标题键必须是字符串,符号将不会显示。 - ajmurmann
这对于通用标头是正确的,但如果您只想像 OP 一样使用 Rails 控制器指定 JSON 格式,则 get(:action, format: :json) 应该可以解决问题。 - yuval
18
新的 RSspec 3 语法将类似于 get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" } - Cyril Duchon-Doris
显示剩余2条评论

40

我在Test::Unit中使用了这个:

@request.env['HTTP_ACCEPT'] = "*/*, application/youtube-client"
get :index

3
同样地,就像Alex Soto在另一个回答中提到的那样,在rspec-rails控制器测试中,您可以使用:request.env["HTTP_ACCEPT"]。 - gerry3
非常感谢,这是唯一在旧的2.3应用程序中使用ActionController :: TestCase为我工作的示例。 - ecoologic
+1 我尝试在头部哈希中使用名为Cookie的键(因为这是我的浏览器发送的),但它没有起作用。然后我执行了request.keys并看到了一个名为HTTP_COOKIE的键。使用它可以正常工作。他们真的应该更好地记录这个。 - Kelvin
真的有效!我也在 https://github.com/rspec/rspec-rails/issues/65 找到了答案。 - Stepan Zakharov
@Sytse Sijbrandij 没有人问过 Test::Unit。问题是关于 rspec 的。 - Bryan Dimas

29

我将在此处添加内容,因为我在尝试在Rails 5.1.rc1中完成此操作时遇到了重大困难。

现在get方法的签名略有不同。

您需要在路径后面指定选项作为关键字参数,例如:

get /some/path, headers: {'ACCEPT' => 'application/json'}

请注意,完整的关键字参数集如下:

params: {},headers: {},env: {},xhr: false,as: :symbol


22

这适用于控制器规范,而不是请求规范:

request.headers["My Header"] = "something"

2
这对我有用,这取决于您如何检索标题,如果您使用的是 request.headersrequest.env - Edgar Ortega
3
注意:这是用于控制器测试,而不是问题中提到的集成测试。 - Franklin Yu
3
无法通过集成测试。但是可以通过控制器测试。 - Petr Gazarov

11
使用RSpec 3,您可以使用以下语法。
get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" }

正如官方 Rspec 文档(链接指向 v3.7)所描述的那样


1
太好了,正是我想要的。谢谢! - Francisco Quintero
无法在控制器规范中工作。 - Erem

10

使用 Rack::Test::Methods 与 rspec

header 'X_YOUR_HEADER_VAR', 'val'
get '/path'

标题变量将作为X-Your-Header-Var传递。


注意:这是针对 Test::Unit 的,不是针对 RSpec。 - Franklin Yu
它指的是 RSpec。 - James Tan
1
是的,在rspec中它为我引发了“undefined method 'header'”错误。 - Евгений Масленков

9
我需要单独设置标题。
request.headers["Accept"] = "application/json"

尝试通过get/delete等方式发送数据在rails4中效果很差,这将导致头部信息丢失并引起烦恼。请避免此类方式发送数据。
{"Accept" => "application/json"}

5
这是否真正回答了原帖问题?如果这是一个新问题,开新帖更好。 - β.εηοιτ.βε
这是用于控制器规范的工作方式:request.headers["Accept"] = "application/json"这是用于请求规范的工作方式:get path, headers: {"Accept" => "application/json"} - Ivan Skotsyk

8
为了同时发送 xhr: true 和 headers,我需要这样做,例如:
my_headers = { "HTTP_ACCEPT": "application/json" }
get my_path, xhr: true, headers: my_headers

1
这是GitHub上的源代码链接:https://github.com/rails/rails/blob/e11a62a9fea6f94d607cfa82fa41cdb690fa0294/actionpack/lib/action_dispatch/testing/integration.rb#L58 - Karl Wilbur
headers = 应该改为 my_headers = 吗? - webaholik
修复了。谢谢 @webaholik。 - Jim Stewart

2
尝试类似以下内容:
get :index, :format => 'json' 

不确定,但可能有效,因为Rails正在寻找该路由的.format;这对我也起作用了。 - Alan
2
如果有人想知道,这只是将“format=json”作为查询参数添加。不同于头字段。 - Kevin Carmody

2

您的问题已经得到回答,但是如果您想将某些内容POST到另一个操作中,则需要执行以下操作:

post :save, {format: :json, application: {param1: "test", param2: "test"}}

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