I\'m looking to send raw post data (e.g. unparamaterized JSON) to one of my controllers for testing:
class LegacyOrderUpdateControllerTest < ActionControl
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))
If you are using RSpec (>= 2.12.0) and writing Request specs, the module that is included is ActionDispatch::Integration::Runner
. If you take a look at the source code you can notice that the post method calls process which accepts a rack_env
parameter.
All this means that you can simply do the following in your spec:
#spec/requests/articles_spec.rb
post '/articles', {}, {'RAW_POST_DATA' => 'something'}
And in the controller:
#app/controllers/articles_controller.rb
def create
puts request.body.read
end
I was searching very long for how to post raw JSON content in a integration test (Rails 5.1). I guess my solution could also help in this case.
I looked up the documentation and source code for the post
method: https://api.rubyonrails.org/v5.1/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-post
This directed me to the process
method for more details: https://api.rubyonrails.org/v5.1/classes/ActionDispatch/Integration/Session.html#method-i-process
Thanks to this, I finally found out what parameters are accepted by the process
and thus post
method.
Here's what my final solution looked like:
post my_url, params: nil, headers: nil, env: {'RAW_POST_DATA' => my_body_content}, as: :json
Using Rails 4, I was looking to do this to test the processing of raw xml that was being posted to the controller. I was able to do it by just providing the string to the post:
raw_xml = File.read("my_raw.xml")
post :message, raw_xml, format: :xml
I believe if the parameter provided is a string, it just gets passed along to the controller as the body.
post :index, {:foo=> 'bar', :bool => 'true'}
In rails, 5.1 the following work for me when doing a delete request that needed data in the body:
delete your_app_url, as: :json, env: {
"RAW_POST_DATA" => {"a_key" => "a_value"}.to_json
}
NOTE: This only works when doing an Integration test.