[rspec-users] I need some guidance

Scott Taylor mailing_lists at railsnewbie.com
Fri Dec 21 14:41:30 EST 2007

On Dec 21, 2007, at 1:30 PM, jimmy zimmerman wrote:

> I'm building an http communicator class for a web service API  
> wrapper and I'm trying to go through the BDD process in doing so.  
> I'm having a bit of a struggle figuring out how to set up the tests  
> in relation to isolating things appropriately as well as testing  
> behavior vs testing implementation.
> Specifically, I'm trying to set up a post method on my  
> HttpCommunicator so I have the following:
> describe FamilyTreeApi::HttpCommunicator, "post" do
> it "should accept an endpoint and an xml string to post" # I'm okay  
> with this one
> it "should perform post content to given endpoint"
> it "should return a response object"
> end
> I have written/passed the tests for the first spec, but I'm having  
> troubles figuring out how to verify behavior for the second and  
> third, and how to mock/stub it up. I'll be using the 'net/https'  
> standard libraries to implement the POST action, and I know that it  
> requires the use of a URI instance, a Net::HTTP instance, and a  
> Net::HTTP::Post request instance.

Yep - I was doing something like that just yesterday, excepting  
fetching a feed with the URI and Net:HTTP classes.

The way I got around it was to write one method which encapsulated  
the behaviour of the URI.parse (stubbing a class method which  
returned a mock).  The second method would wrap the first - so  
something like this:

def get_parsed_url

def get_feed

This allows me to stub out get_parsed_url when I'm testing the  
get_feed method, and ignore the URI class altogether.

Another way to get around this sort of thing is by passing mock  
objects into constructors, a la "Dependency Injection".  That would  
go something like this:

class Foo
   def initialize(http_class = Net::HTTP, uri_class = URI)
     @http_class, @uri_class = http_class, uri_class

   def get_parsed_url

   def get_feed

This allows you to pass in mock objects (mock classes) for your  
tests, but it still allows the production code to default to what you  
really want (the Net::HTTP and URI classes).  It's also going to make  
your code more flexible, in the case that you ever wanted to swap out  
Net::HTTP or URI for an alternative implementation.

Hope that helps,


More information about the rspec-users mailing list