How to send raw post data in a Rails functional test?

I ran across the same issue today and found a solution.

In your test_helper.rb define the following method inside of ActiveSupport::TestCase:

def raw_post(action, params, body)
  @request.env['RAW_POST_DATA'] = body
  response = post(action, params)
  @request.env.delete('RAW_POST_DATA')
  response
end

In your functional test, use it just like the post method but pass the raw post body as the third argument.

class LegacyOrderUpdateControllerTest < ActionController::TestCase
  test "sending json" do
    raw_post :index, {}, {:foo => "bar", :bool => true}.to_json
  end
end

I tested this on Rails 2.3.4 when reading the raw post body using

request.raw_post

instead of

request.body.read

If you look at the source code you'll see that raw_post just wraps request.body.read with a check for this RAW_POST_DATA in the request env hash.


I actually solved the same issues just adding one line before simulating the rspec post request. What you do is to populate the "RAW_POST_DATA". I tried to remove the attributes var on the post :create, but if I do so, it do not find the action.

Here my solution.

def do_create(attributes)
  request.env['RAW_POST_DATA'] = attributes.to_json
  post :create, attributes
end 

In the controller the code you need to read the JSON is something similar to this

  @property = Property.new(JSON.parse(request.body.read))