簡體   English   中英

使用rspec在控制器中調用API調用

[英]Stubbing API calls in controller with rspec

我只是有點困惑為什么我不能在我的控制器規范中存根局部變量。

這是我的控制器:

Class UsersController < ApplicationController
    ...
    def get_company
        resp = Net::HTTP.get("http://get_company_from_user_id.com/#{params[:id]}.json")
        @resp = JSON.parse(resp.body)
        ...

我的規格如下:

class ResponseHelper
    def initialize(body)
        @body = body
    end
end

describe "Get company" do
it "returns successful response" do
        stub_resp_body = '{"company": "example"}' 
        stub_resp = ResponseHelper.new(stub_resp_body)
    controller.stub!(:resp).and_return(stub_resp)
    get :get_company, {:id => @test_user.id}
    expect(response.status).to eq(200)
    end
end

我仍然得到一個錯誤說:

 Errno::ECONNREFUSED:
 Connection refused - connect(2)

我究竟做錯了什么? 如果我正在對resp變量進行存根,為什么它仍然在嘗試執行HTTP請求?在這種情況下如何存根resp變量?

你只是不能存根本地變量,你只能存根方法。 在您的情況下,您可以存根Net::HTTP.get方法:

Net::HTTP.stub(:get).and_return(stub_resp)

沒有“存在局部變量”之類的東西。 唯一可以存根的是方法調用。

您需要使用存根Net::HTTP.get調用來返回看起來像Net::HTTPResponse的其他代碼可以使用的內容。

我經常喜歡通過為每個API知道如何從參數生成url(在本例中為id)以及如何解析響應的客戶端類來整理它。 這樣可以將這些細節保留在控制器之外,並且還可以輕松進行測試,因為現在您可以提供模擬客戶端對象

您不能存根本地變量。 只是一種方法。 由於上面有答案,您可能希望存根Net :: HTTP.get調用。 但是,如果您不希望代碼依賴於特定的HTTP客戶端庫,則可以將http請求提取到控制器的另一個方法中並存根此方法

Class UsersController < ApplicationController
...
def get_company
    resp = make_request(params[:id)
    @resp = JSON.parse(resp.body)
end

protected

def make_request(id)
  Net::HTTP.get('http://get_company_from_user_id.com/#{id}.json')
end


controller.
  should_receive(:make_request).
  with(@test_user.id).
  and_return(stub_resp)

暫無
暫無

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

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