Specifying Content Type in rspec
Solution 1
There's a way to do this described in this thread -- it's a hack, but it seems to work:
@request.env["HTTP_ACCEPT"] = "application/json"
json = { ... data ... }.to_json
post :create, :some_param => json
Solution 2
In Rails 3, you can skip the header and @request.env
stuff and just add a format
parameter to your post call, e.g.:
post :create, format: :json, param: 'Value of Param'
Solution 3
A lot of frustration and variations and that's what worked for me. Rails 3.2.12 Rspec 2.10
@request.env["HTTP_ACCEPT"] = "application/json"
@request.env["CONTENT_TYPE"] = "application/json"
put :update, :id => 1, "email" => "[email protected]"
Solution 4
First of all, you don't want to test the built-in conversion of json to hash. Same applies to xml.
You test controller with data as hashes, not bothering wether it's json, xml or from a html form.
But if you would like to do that as an exercise, this is a standalone ruby script to do play with :)
require 'json'
url = URI.parse('http://localhost:3030/mymodels.json')
request = Net::HTTP::Post.new(url.path)
request.content_type="application/json"
request.basic_auth('username', 'password') #if used, else comment out
hash = {:mymodel => {:name => "Test Name 1", :description => "some data for testing description"}}
request.body = hash.to_json
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
puts response
to switch to xml, use content_type="text/xml"
and
request.body = "<?xml version='1.0' encoding='UTF-8'?><somedata><name>Test Name 1</name><description>Some data for testing</description></somedata>"
Solution 5
A slightly more elegant test is to use the header helper:
header "HTTP_ACCEPT", "application/json"
json = {.... data ....}.to_json
post '/model1.json', json
Now this does exactly the same thing as setting @env
; it's just a bit prettier.
Related videos on Youtube
skeevis
Updated on May 07, 2022Comments
-
skeevis about 2 years
I'm trying to build an rspec test that sends JSON (or XML) via POST. However, I can't seem to actually get it working:
json = {.... data ....}.to_json post '/model1.json',json,{'CONTENT_TYPE'=>'application/json'}
and this
json = {.... data ....}.to_json post '/model1.json',json,{'Content-Type'=>'application/json'}
any ideas? THANKS!
-
BeepDog over 13 yearsThis works with Rspec 2 and rails 3. (and was extremely difficult to find) Actually, I had to not use .to_json on the thing to get it to behave correctly. Otherwise, everything else worked fine.
-
Salil almost 12 yearsThank you. I had a hard-time searching for solution to my failing tests before reading your answer.
-
sorens over 11 yearsI also found that
request.accept = 'application/json'
will work as well. -
Paul Brannan over 11 yearsWhere is this method defined? I get a NoMethodError when I try to call it.
-
Kevin Gauthier over 11 years@PaulBrannan It's in rack/test
-
Romain Champourlier almost 11 yearsThanks! I found out the one to work for me thanks to your answer:
@request.env["CONTENT_TYPE"] = "application/json"
. -
Dennis over 9 yearsDoes using
format: :json
setrequest.accept
andrequest.content_type
to"application/json"
? -
Dennis over 9 yearsThis issue on rspec-rails implies that
format: :json
is the same asrequest.accept = "application/json"
. -
dkniffin over 7 yearsIt looks like in later versions of rails/rspec,
format: :json
got changed toas: :json