Ruby on rails JSON Rails API的功能测试

Ruby on rails JSON Rails API的功能测试,ruby-on-rails,json,ruby-on-rails-4,functional-testing,rails-api,Ruby On Rails,Json,Ruby On Rails 4,Functional Testing,Rails Api,我目前正在构建一个由Rails/Rails API支持的JSON API。我有一条通过补丁请求接受JSON发送的路由,还有一个before过滤器,需要访问原始请求/JSON 出于测试目的,我在过滤器之前添加了以下内容以显示我的问题: before_filter do puts "Raw Post: #{request.raw_post.inspect}" puts "Params: #{params.inspect}" end 以下curl请求按预期工作: curl -X PATCH

我目前正在构建一个由Rails/Rails API支持的JSON API。我有一条通过补丁请求接受JSON发送的路由,还有一个before过滤器,需要访问原始请求/JSON

出于测试目的,我在过滤器之前添加了以下内容以显示我的问题:

before_filter do
  puts "Raw Post: #{request.raw_post.inspect}"
  puts "Params: #{params.inspect}"
end
以下curl请求按预期工作:

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"}

但是,我无法测试此方法,以下调用均无效:

  • 包含参数,但不作为JSON传输

    test 'passing hash' do
      patch :update, { key: "value" }
    end
    
    # Raw Post: "key=value"
    # Params: {"key"=>"value", "controller"=>"posts", "action"=>"update"}
    
  • 包含参数,但同样不作为JSON传输

    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格式,但不包括在参数中

    test 'passing JSON' do
      patch :update, { key: "value" }.to_json
    end
    
    # Raw Post: "{\"key\":\"value\"}"
    # Params: {"controller"=>"posts", "action"=>"update"}
    
    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"}
    
  • JSON格式,但不包括在参数中

    test 'passing JSON' do
      patch :update, { key: "value" }.to_json
    end
    
    # Raw Post: "{\"key\":\"value\"}"
    # Params: {"controller"=>"posts", "action"=>"update"}
    
    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"}
    
这个列表甚至更长,我只是想告诉你我的问题。我还测试了将
Accept
Content-Type
标题设置为
application/json
,似乎没有任何帮助。我是否做错了什么,或者这是Rails功能测试中的一个bug

这是,由这个问题的同一位作者报道的。在Rails 5之前,它不太可能被修复,或者通过查看已分配给它的里程碑,它看起来是这样的

如果您像我一样,在处理这个问题几个小时后,在不知道它确实是一个bug的情况下来到这里,也许您想知道您可以在集成测试中做到这一点:

$rails g integration\u test my\u integration\u 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
需要“测试助手”
类MyIntegrationTestTestMime::JSON,'Content Type'=>Mime::JSON.to_s}
断言:成功
assert_equal'application/json',response.headers['Content-Type']
assert_not_nil分配:所有者
断言等于“我的新名字”,分配(:owner).name
结束
结束

我将此标记为答案,因为这是解决此问题的最佳方法。经验教训:根本不使用功能测试,进行完整的集成测试。Rails 6是如何做到这一点的?测试文档没有给出示例。