[英]Stubbing API calls in controller with rspec
I am just a little confused at why I can't stub a local variable in my controller spec. 我只是有点困惑为什么我不能在我的控制器规范中存根局部变量。
Here is my controller: 这是我的控制器:
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)
...
My spec looks like: 我的规格如下:
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
I still get an error saying that: 我仍然得到一个错误说:
Errno::ECONNREFUSED:
Connection refused - connect(2)
What am I doing wrong? 我究竟做错了什么? If I am stubbing the
resp
variable why is it still trying to do the HTTP request and how would I stub the resp
variable in this case? 如果我正在对
resp
变量进行存根,为什么它仍然在尝试执行HTTP请求?在这种情况下如何存根resp
变量?
You just cannot stub a local variable, you can only stub methods. 你只是不能存根本地变量,你只能存根方法。 In your case you can stub the
Net::HTTP.get
method: 在您的情况下,您可以存根
Net::HTTP.get
方法:
Net::HTTP.stub(:get).and_return(stub_resp)
There is no such thing as 'stubbing a local variable'. 没有“存在局部变量”之类的东西。 The only thing that can be stubbed are method calls.
唯一可以存根的是方法调用。
You would need the stub the Net::HTTP.get
call to return something that looks like a Net::HTTPResponse
that the rest of your code can work with. 您需要使用存根
Net::HTTP.get
调用来返回看起来像Net::HTTPResponse
的其他代码可以使用的内容。
I quite often like to tidy this up by having a client class for each api that knows how to generate the url from the arguments (in this case the id) and how to parse the response. 我经常喜欢通过为每个API知道如何从参数生成url(在本例中为id)以及如何解析响应的客户端类来整理它。 This keeps those details out of the controller and also makes testing easy, since now you can provide a mock client object
这样可以将这些细节保留在控制器之外,并且还可以轻松进行测试,因为现在您可以提供模拟客户端对象
You cannot stub a local variable. 您不能存根本地变量。 Just a method.
只是一种方法。 As there were answers above you may want to stub Net::HTTP.get call.
由于上面有答案,您可能希望存根Net :: HTTP.get调用。 However, if you don't want to have you code rely upon a particular HTTP client library you can extract the http request into another method of a controller and stub this method
但是,如果您不希望代码依赖于特定的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.