簡體   English   中英

如何在 rails 3 功能測試中發布 JSON 數據

[英]How to post JSON data in rails 3 functional test

我計划在我的項目中的請求和響應中都使用 JSON 數據,並且在測試中遇到了一些問題。

經過一段時間的搜索,我發現以下代碼使用curl發布 JSON 數據:

curl -H "Content-Type:application/json" -H "Accept:application/json" \
    -d '{ "foo" : "bar" }' localhost:3000/api/new

在 controller 中,我可以簡單地使用params[:foo]訪問 JSON 數據,這非常簡單。 但是對於功能測試,我只找到postxhrxml_http_request的別名)。

如何在 rails 中編寫功能測試以達到與使用curl相同的效果? 還是我應該以其他方式進行測試?

這是我嘗試過的。 我在action_controller/test_case.rb中找到了xhr的實現,並嘗試添加jhr方法,只需更改“Conetent-Type”和“HTTP_ACCEPT”。 (添加在test/test_helpers.rb 。)

def json_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
  @request.env['Content-Type'] = 'Application/json'
  @request.env['HTTP_ACCEPT'] ||= [Mime::JSON, Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
  __send__(request_method, action, parameters, session, flash).tap do
    @request.env.delete 'Content-Type'
    @request.env.delete 'HTTP_ACCEPT'
  end
end
alias jhr :json_http_request

我以與xhr相同的方式使用它,但它不起作用。 我檢查了@response object 並看到身體是" "

我還在 Stack Overflow 上找到了一個類似的問題,但它適用於 rails 2,而發布原始數據的答案在 rails 3 中不起作用。

從 Rails 5 開始,這樣做的方法是:

post new_widget_url, as: :json, params: { foo: "bar" }

這也將正確設置Content-type header (到application/json )。

我發現這正是我想要的——將 JSON 發布到控制器的操作中。

post :create, {:format => 'json', :user => { :email => "test@test.com", :password => "foobar"}}

只需指定適當的內容類型:

post :index, '{"foo":"bar", "bool":true}', "CONTENT_TYPE" => 'application/json'

Json 數據應將 go 作為字符串,而不是作為 Hash。 查看運行測試的堆棧跟蹤,您可以獲得對請求准備的更多控制: ActionDispatch::Integration::RequestHelpers.post => ActionDispatch::Integration::Session.process => Rack::Test::Session.env_for

指定:格式不起作用,因為請求 go 為 'application/x-www-form-urlencoded' 並且 json 未正確解析處理請求正文。

假設您有一個controller名為Z8A5DA52ED126447D359E70C05721A8AAAZ,一種名為new的方法,您正在測試Z8A5DA52252525259EB12647D37D359D359D359D359EBEN

@request.env["RAW_POST_DATA"] = '{ "foo" : "bar" }'
post :new

為我做了伎倆。

這是一個片段,讓我發布 json 數據來測試我自己的應用程序。 導軌 3

port = Rails.env.production? ? 80 : 3000
uri = URI.parse( Rails.application.routes.url_helpers.books_url(:host => request.host, :port => port, :format => :json) )
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.content_type = 'application/json'
request.body = @json_data
response = http.request( request )
@result = response.body

希望這對其他人有幫助

正如@taro 在上面的評論中所建議的那樣,在功能和集成測試中對我有用的語法是:

post :create, {param1: 'value1', param2: 'value2', format: 'json'}

(花括號並不總是必需的,但有時如果缺少它們就不起作用,所以我總是添加它們。)

這是此類帖子的 params 和 request.format 的樣子:

參數:{"param1"=>"value1", "param2"=>"value2", "format"=>"json", "controller"=>"things", "action"=>"create"}

request.format:應用程序/json

我能想到的最好的答案是你沒有

不管是不是故意的,rails 沒有為你實現這個可能是件好事。

在功能測試中,你真的只想測試你的 controller 而不是rails 的反序列化方法,甚至路由和 mime 檢測都設置正確,這些都屬於 IntegrationTest。

因此,對於您的控制器,不要像往常一樣傳遞 JSON 只需傳遞參數 hash 即可。 如果您需要檢查並做出不同的響應,也許還可以添加:格式作為參數。

如果您想測試完整的堆棧,請移至IntegrationTest

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM