Pregunta

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?

¿Fue útil?

Solución

This is a bug, reported by same author of this question. It is not likely to be fixed until Rails 5, or so it seems by looking at the milestone it has been assigned to.

If you land here, like me, after some hours dealing with this issue unknowing that it is really a bug, maybe you want to know that you can do that in an Integration test:

$ rails g integration_test my_integration_test

require 'test_helper'

class MyIntegrationTestTest < ActionDispatch::IntegrationTest
  setup do
    @owner = Owner.create(name: 'My name')
    @json = { name: 'name', value: 'My new name' }.to_json
  end

  test "update owner passing json" do
    patch "/owners/#{@owner.id}", 
      @json,
      { 'Accept' => Mime::JSON, 'Content-Type' => Mime::JSON.to_s}

    assert_response :success
    assert_equal 'application/json', response.headers['Content-Type']
    assert_not_nil assigns :owner
    assert_equal 'My new name', assigns(:owner).name
  end
end
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top