title: How to post JSON data in rails 3 functional test
body: <p>I plan to use JSON data in both request and response in my project and having some problems in testing.</p>
  
  <p>After searching for a while, I find the following code which uses <code>curl</code> to post JSON data:</p>
  
  <pre><code>curl -H "Content-Type:application/json" -H "Accept:application/json" \
      -d '{ "foo" : "bar" }' localhost:3000/api/new
  </code></pre>
  
  <p>In the controller I can access the JSON data simply using <code>params[:foo]</code> which is really easy. But for functional testing, I only find <code>post</code> and <code>xhr</code> (alias for <code>xml_http_request</code>).</p>
  
  <p><strong>How can I write functional test in rails to achieve the same effect as using <code>curl</code>? Or should I do test in other ways?</strong></p>
  
  <p>Here's what I've tried. I find the implementation for <code>xhr</code> in <code>action_controller/test_case.rb</code>, and tried to add <code>jhr</code> method simply changing 'Conetent-Type' and 'HTTP_ACCEPT'. (Added in <code>test/test_helpers.rb</code>.)</p>
  
  <pre><code>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
  </code></pre>
  
  <p>I used this in the same way as <code>xhr</code>, but it does not work. I inspected the <code>@response</code> object and sees the body is <code>" "</code>.</p>
  
  <p>I also find <a href="https://stackoverflow.com/questions/2103977/how-to-send-raw-post-data-in-a-rails-functional-test">one similar question</a> on Stack Overflow but it's for rails 2 and the answer for posting raw data does not work in rails 3.</p>