Functional testing of a JSON Rails API

2 min read Original article ↗

I'm currently building a JSON API powered by Rails/rails-api. I have a route which accepts JSON send via a PATCH request and a before filter which needs access to the raw request/JSON.

For testing purposes I added following before filter to show my problem:

before_filter do
  puts "Raw Post: #{request.raw_post.inspect}"
  puts "Params: #{params.inspect}"
end

The following curl request works as intended:

curl -X PATCH -H "Content-Type: application/json" -d '{"key":"value"}' http://localhost:3000/update

# Raw Post: "{\"key\":\"value\"}"
# Params: {"key"=>"value", "action"=>"update", "controller"=>"posts"}

However I fail testing this method, none of the following calls do work:

  • Params included, but not as JSON transferred

    test 'passing hash' do
      patch :update, { key: "value" }
    end
    
    # Raw Post: "key=value"
    # Params: {"key"=>"value", "controller"=>"posts", "action"=>"update"}
    
  • Params included, but again not as JSON transferred

    test 'passing hash, setting the format' do
      patch :update, { key: "value" }, format: :json
    end
    
    # Raw Post: "key=value"
    # Params: {"key"=>"value", "controller"=>"posts", "action"=>"update", "format"=>"json"}
    
  • JSON format, but not included in params

    test 'passing JSON' do
      patch :update, { key: "value" }.to_json
    end
    
    # Raw Post: "{\"key\":\"value\"}"
    # Params: {"controller"=>"posts", "action"=>"update"}
    
  • JSON format, but not included in params

    test 'passing JSON, setting format' do
      patch :update, { key: "value" }.to_json, format: :json
    end
    
    # Raw Post: "{\"key\":\"value\"}"
    # Params: {"format"=>"json", "controller"=>"posts", "action"=>"update"}
    

This list is even longer, I just wanted to show you my problem. I tested setting both the Accept and Content-Type headers to application/json too, nothing seems to help. Am I doing something wrong, or is this a bug in Rails' functional tests?