2015-04-23 58 views
2

我有一個包含一個方法和一些條件語句的控制器。以下是該控制器的示例。如何在rspec中存儲HTTP POST請求?

class <controllername> < ApplicationController 
def method 
    if params["c"] 
    http = Net::HTTP.new(uri.host, uri.port) 
    req = Net::HTTP::Post.new("api_url_here") 
    response = http.request(req) 
    array = JSON.parse(response.body) 
    url = params["s"] 
    ..... 
    elsif params["e"] 
    ..... 
    else 
    ..... 
    end 
end 
end 

我寫的RSpec對上述控制器

it "should do something" do 
    array ="some array values" 
    get :method, {"c" => "value for c", "s" => "value for s"} 
    expect(response).to have_http_status(200) 
end 

我知道上面RSpec的方法是完全錯誤的。當這種情況下運行arrayresponse的值是由post獲得method內部的呼叫和responseHTTPBADREQUEST如預期。

我要的是

存根在規範的情況下陣列和響應(將需要以後的操作中,這些數值)我的規格情況下,這些價值觀念,不調用HTTP POST ::裏面的method

回答

1

因爲它們是局部變量,所以你不能幹淨地模擬http,req或response。考慮使它們成爲類或實例變量,以便可以覆蓋它們。

更好的是,使用正確的工具來完成這項工作。我建議使用vcr測試,以便可以嘲笑整個HTTP堆棧。使用錄像機,您可以錄製請求並在測試中回放,以便您可以獲得確切的模擬出的數據。

https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/getting-started

+0

謝謝合作! 。但是,如果我只想以'array = JSON.parse(response.body)'的方式模擬'array',並且只有使用模擬設置的值將被使用,那麼我應該使用什麼使用。 – Rocky29

+1

我的答覆仍然是一樣的。變量'''array'''仍然是一個實例變量,並且不會公開用於模擬。錄像機真的會是你正確測試整個系統的最佳選擇。 – PressingOnAlways

3

你可以嘲笑答案

expect_any_instance_of(Net::HTTP::Post).to receive(:request) { response_data_here } 

您也可以使用錄像機:https://github.com/vcr/vcr

當你第一次運行VCR,它會做真正的請求,並保存響應作爲夾具,第二次它將使用夾具並避免真正的http請求

+1

需要注意的是rspec開發人員不鼓勵使用''expect_any_instance_of''' - http://www.relishapp.com/rspec/rspec-mocks/v/3-1/docs/working-with-legacy-代碼/任何實例。 – PressingOnAlways

1

錄像機非常方便,但因爲它總是在第一次運行真正的請求時不會讓你嘲笑任何你喜歡的響應。

嘗試fakeweb,它可以讓你做到這一點。你可以嘲笑你的URL的所有請求,如:

FakeWeb.register_uri(:get, "http://my-url.com", :body => "my mock response") 

似乎不超過一年已經被更新了,但還是應該爲Rails 3和4