Balaji Radhakrishnan
Balaji Radhakrishnan

Reputation: 1050

How to stub HTTP POST request in rspec?

I have a controller which contains a method and some conditional statements. the following is a sample of that controller.

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

I wrote rspec for the above controller

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

I know the above rspec method is completely wrong. when this case runs the value for array and response are obtained by post call inside method and the response is HTTPBADREQUEST as expected.

What I want is

To stub those values for array and response in the spec case(these values will be needed for later operations) and my spec case to not call HTTP::POST inside the method

Upvotes: 4

Views: 22699

Answers (3)

Michael Cho
Michael Cho

Reputation: 746

VCR is pretty handy, but since it always runs the real request the first time it's not as flexible in allowing you to mock any response that you like.

Try fakeweb, which lets you do just that. You can mock all requests to your URL like:

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

It doesn't seem to have been updated for over a year, but should still work for Rails 3 and 4.

Upvotes: 2

rorra
rorra

Reputation: 9693

you can mock the answer

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

You can also use VCR: https://github.com/vcr/vcr

When you run VCR for the first time, it will do the real request and save the response as a fixture, the second time it will use the fixture and avoid the real http request

Upvotes: 3

PressingOnAlways
PressingOnAlways

Reputation: 12356

You won't be able to cleanly mock out http, req, or response because they are local variables. Consider making them class or instance variables such that you can override them.

Better yet, use the right tool for the job. I recommend using vcr tests so that you can mock out the entire HTTP stack. With VCR, you can record a request and play it back in your tests so you can get the exact mocked out data that you.

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

Upvotes: 1

Related Questions