2010-10-27 43 views
19

我試圖構建一個通過POST發送JSON(或XML)的rspec測試。不過,我似乎無法真正得到它的工作:在rspec中指定內容類型

json = {.... data ....}.to_json 
    post '/model1.json',json,{'CONTENT_TYPE'=>'application/json'} 

json = {.... data ....}.to_json 
    post '/model1.json',json,{'Content-Type'=>'application/json'} 

什麼想法?謝謝!

+0

通常你POST在控制器的動作。你爲什麼張貼到一個文件? – 2010-10-27 23:15:35

+0

這是一個RESTful模型 – skeevis 2010-10-28 01:28:57

回答

17

有一種方法在this thread這說明做 - 這是一個黑客,但它似乎工作:

@request.env["HTTP_ACCEPT"] = "application/json" 
json = { ... data ... }.to_json 
post :create, :some_param => json 
+3

這適用於Rspec 2和rails 3.(並且極難找到) 實際上,我不得不使用.to_json來使它正常工作。否則,一切工作正常。 – BeepDog 2011-02-18 21:04:41

+0

謝謝。在閱讀您的答案之前,我已經很難找到解決我的失敗測試的解決方案。 – Salil 2012-06-05 08:35:48

+0

是的,這仍然適用於RSpec 3('rspec(2.11.0)')。好極了。 – sorens 2012-11-02 18:29:48

5

首先,你不想要測試的內置JSON的轉換散列。同樣適用於xml。

你測試控制器的數據作爲散列,而不是打擾它的JSON,XML或從一個HTML表單。

但是,如果你想這樣做,作爲一個練習,這是一個獨立的Ruby腳本做把玩:)

require 'json' 
url = URI.parse('http://localhost:3030/mymodels.json') 
request = Net::HTTP::Post.new(url.path) 
request.content_type="application/json" 
request.basic_auth('username', 'password') #if used, else comment out 

hash = {:mymodel => {:name => "Test Name 1", :description => "some data for testing description"}} 
request.body = hash.to_json 
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)} 
puts response 

切換到XML,使用content_type="text/xml"

request.body = "<?xml version='1.0' encoding='UTF-8'?><somedata><name>Test Name 1</name><description>Some data for testing</description></somedata>" 
2

一個稍微更優雅的測試是使用標頭助手:

header "HTTP_ACCEPT", "application/json" 
json = {.... data ....}.to_json 
post '/model1.json', json 

現在,這確實是th與設置@env相同的東西;它只是更漂亮一點。

+0

這個方法在哪裏定義?當我嘗試調用它時,我得到一個NoMethodError。 – 2012-11-29 20:35:16

+0

@PaulBrannan這是[在機架/測試](https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb#L134) – 2012-11-29 20:49:24

14

在Rails 3,您可以跳過頭和@request.env的東西,只需添加一個format參數到您的文章通話,例如:

post :create, format: :json, param: 'Value of Param' 
+0

是否使用'format :: json' set' request.accept'和'request.content_type'到''application/json「'? – Dennis 2014-11-24 15:59:01

+0

[rspec-rails上的這個問題](https://github.com/rspec/rspec-rails/issues/710)意味着'format :: json'與request.accept =「application/json」相同'。 – Dennis 2014-11-24 16:10:45

+1

看起來在rails/rspec的後期版本中,'format :: json'變成'as :: json' – dkniffin 2016-12-05 18:55:17

9

太多的無奈和變化,這對我工作。 的Rails 3.2.12 Rspec的2.10

@request.env["HTTP_ACCEPT"] = "application/json" 
@request.env["CONTENT_TYPE"] = "application/json" 
put :update, :id => 1, "email" => "[email protected]" 
+1

謝謝!我找到了一個爲我工作的感謝您的答案:'@ request.env [「CONTENT_TYPE」] =「application/json」'。 – rchampourlier 2013-05-31 09:05:05

+0

如果您希望控制器返回JSON,則還需要HTTP_ACCEPT ... – rchampourlier 2013-05-31 09:31:58

0

,我發現來測試這些東西的最佳方式是與要求的測試。請求測試通過Rails的完整參數解析和路由階段。所以,我可以寫這樣一個測試:

request_params = {:id => 1, :some_attribute => "some value"} 
headers = {'Accept' => 'application/json', 'Content-Type' => 'application/json'} 
put "/url/path", request_params.to_json, headers 
expect(response).to be_success 
0

我認爲你可以用headers PARAM指定標題:

post '/model1.json', headers: {'Content-type': 'application/json'} 

how provide JSON data的Rspec的文檔。

0
@request.env["CONTENT_TYPE"] = "application/json" 

,或傳入請求

"CONTENT_TYPE" => "application/json"