Reputation: 1793
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?
Upvotes: 3
Views: 3541
Reputation: 1127
You cannot stub a local variable. Just a method. As there were answers above you may want to stub Net::HTTP.get call. 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
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)
Upvotes: 3
Reputation: 84114
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.
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. This keeps those details out of the controller and also makes testing easy, since now you can provide a mock client object
Upvotes: 4
Reputation: 19228
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.stub(:get).and_return(stub_resp)
Upvotes: 6