ChatGPT解决这个技术问题 Extra ChatGPT

How to set request headers in rspec request spec?

In the controller spec, I can set http accept header like this:

request.accept = "application/json"

but in the request spec, "request" object is nil. So how can I do it here?

The reason I want to set http accept header to json is so I can do this:

get '/my/path'

instead of this

get '/my/path.json'

c
chriscz

You should be able to specify HTTP headers as the third argument to your get() method as described here:

http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-get

and here

http://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html#method-i-process

So, you can try something like this:

get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}

We needed to use 'HTTP_ACCEPT': get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
NOTE: This is for integration testing, similar to comment below, in rspec-rails controller tests, you would use: request.env["HTTP_ACCEPT"] =
Small gotcha that I ran into because I am silly: The header keys have to be Strings. Symbols will not show up.
@ajmurmann Now symbols work: "Authorization" header can be :authorization.
New RSspec 3 syntax would be like get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" } `
S
Sytse Sijbrandij

I used this in Test::Unit:

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

Similarly, as Alex Soto notes in a comment on another answer, in rspec-rails controller tests, you can use: request.env["HTTP_ACCEPT"]
thanks a lot dude, only example that worked for me on an old 2.3 app with ActionController::TestCase
+1 I tried using a key named Cookie in the headers hash (because that's what my browser sends), but it didn't work. Then I did request.keys and saw a key named HTTP_COOKIE. Using that worked. They really should document this better.
It really works! I also found that answer in github.com/rspec/rspec-rails/issues/65
@Sytse Sijbrandij Nobody asked about Test::Unit. Question asked about rspec.
J
Jules Copeland

I'm adding this here, as I got majorly stuck trying to do this in Rails 5.1.rc1

The get method signature is slightly different now.

You need to specify the options after the path as keyword arguments, i.e.

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

FYI, the full set of keywords arguments are:

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


s
slhck

This is working for controller specs, not request specs:

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

This worked for me, it depends on how are you retrieving the headers, if you are using request.headers or request.env
Note: This is for controller tests, not integration tests mentioned in the question.
didn't work for integration tests. Works with controller tests, however.
m
marcusb

Using rspec with Rack::Test::Methods

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

The header var will come through as X-Your-Header-Var


Note: this is for Test::Unit, not for RSpec.
its indicating rspec
Yeah. In rspec it raises ndefined method 'header' error for me.
u
user4694178

I have to set up headers separately

request.headers["Accept"] = "application/json"

Trying sending it via get/delete/.... is complete garbage in rails4 and causing pain in my head because it is never send as header but as parameter.

{"Accept" => "application/json"}

Does this really provide an answer to the OP question ? If it is a new question, it is a better idea to open up a new question.
C
Cyril Duchon-Doris

With RSpec 3 you can use the following syntax

get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" }

As described in the official Rspec documentation (the link points to v3.7)


Sweet. Just what I was looking for. Thanks!
Won't work in a controller spec.
J
Jim Stewart

To send both xhr: true and headers, I had to do e.g.:

my_headers = { "HTTP_ACCEPT": "application/json" }
get my_path, xhr: true, headers: my_headers

Here's the source code on GitHub: github.com/rails/rails/blob/…
Shouldn't headers = be my_headers = ?
Fixed. Thanks @webaholik.
I
Igor Escobar

Your question was already answered but in case you want to POST something to another action you have to do this:

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

S
Sergio Tulentsev

Try something like:

get :index, :format => 'json' 

Not sure, but probably works because the rails is looking for .format for that route; this happened to work for me too.
In case anyone is wondering, this just adds format=json as a query param. Not the same as a header field.