Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to post JSON data in rails 3 functional test

I plan to use JSON data in both request and response in my project and having some problems in testing.

After searching for a while, I find the following code which uses curl to post JSON data:

curl -H "Content-Type:application/json" -H "Accept:application/json" \
    -d '{ "foo" : "bar" }' localhost:3000/api/new

In the controller I can access the JSON data simply using params[:foo] which is really easy. But for functional testing, I only find post and xhr (alias for xml_http_request).

How can I write functional test in rails to achieve the same effect as using curl? Or should I do test in other ways?

Here's what I've tried. I find the implementation for xhr in action_controller/test_case.rb, and tried to add jhr method simply changing 'Conetent-Type' and 'HTTP_ACCEPT'. (Added in test/test_helpers.rb.)

def json_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
  @request.env['Content-Type'] = 'Application/json'
  @request.env['HTTP_ACCEPT'] ||= [Mime::JSON, Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
  __send__(request_method, action, parameters, session, flash).tap do
    @request.env.delete 'Content-Type'
    @request.env.delete 'HTTP_ACCEPT'
  end
end
alias jhr :json_http_request

I used this in the same way as xhr, but it does not work. I inspected the @response object and sees the body is " ".

I also find one similar question on Stack Overflow but it's for rails 2 and the answer for posting raw data does not work in rails 3.

like image 582
cyfdecyf Avatar asked Apr 30 '11 10:04

cyfdecyf


2 Answers

As of Rails 5, the way to do this is:

post new_widget_url, as: :json, params: { foo: "bar" }

This will also set the Content-type header correctly (to application/json).

like image 172
Paul Cantrell Avatar answered Sep 28 '22 08:09

Paul Cantrell


I found that this does exactly what I want – post JSON to a controller's action.

post :create, {:format => 'json', :user => { :email => "[email protected]", :password => "foobar"}}
like image 40
Sebastian Wramba Avatar answered Sep 28 '22 08:09

Sebastian Wramba