views:

722

answers:

6

I'm working on an application that reaches out to a web service. I'd like to develop a proxy class that returns a fake response from the service, so I don't have to constantly be hitting it with requests while I'm developing/testing other parts of the app.

My application is expecting a response generated via Net::HTTP.

response = Net::HTTP.get(URI.parse('http://foo.com'))

case response
when Net::HTTPOK
  # do something fun

when Net::HTTPUnauthorized
  # you get the idea

How can I manufacture a response object, give it all the right headers, return a body string, etc?

response = ProxyClass.response_object

case response
when Net::HTTPOk
  # my app doesn't know it's being lied to

Thanks.

+2  A: 

I would look into a mocking library like mocha.

Then you should be able to setup a mock object to help test:

def setup
 @http_mock = mock('Net::HTTPResponse')
 @http_mock .stubs(:code => '200', :message => "OK", :content_type => "text/html", :body => '<title>Test</title><body>Body of the page</body>')
end

See the Tim Stephenson's RaddOnline blog for a more complete tutorial, where I snagged this example.

csexton
+5  A: 

I would start with FakeWeb and see if that meets your needs. If it doesn't you can probably gut whatever you need out of the internals and create your own solution.

dasil003
A: 

I would either use FakeWeb as mentioned above, or have my rake test task start a Webrick instance to a little sinatra app which mocks the various test responses you're hoping to see.

angryamoeba
+1  A: 

For testing a web service client, we use Sinatra, a lovely little lightweight web framework that lets you get something up and running very quickly and easily. Check out the home page; it has an entire Hello World app in 5 lines of code, and two commands to install and run the whole thing.

Brian Campbell
A: 

You could look into using Rack for this which should allow you to do everything you need.

nkassis
A: 

It's actually not that hard to roll your own fake responses directly with Net::HTTP. Here's a simple 200 OK with a cookie header:

def fake_response
  net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
  net_http_resp.add_field 'Set-Cookie', 'Monster'
  RestClient::Response.create("Body goes here", net_http_resp, nil)
end

Since few of us are using raw Net::HTTP anymore, the (optional) last line wraps it up as a RestClient::Response, which can then be stubbed into RestClient:

stub(RestClient).post(anything) { fake_response }
jpatokal