Topic: Stubbing / mocking a call to a URL

We have a Url class which Factory Girl is generating like so:

Factory.define :url do |f|
  f.sequence(:url) { |n| "http://website#{n}.com" }
  f.sequence(:some_value) { |n| n }
end

The Url class needs to validate that the Url#url document body has Url#some_value contained within it. We're successfully parsing the Url#url and searching for the Url#some_value. However, introducing this validation causes errors across our test suite because it was previously assumed that all Urls were valid.

Obviously I would like to test the validation in isolation (which I've done), but I don't know the cleanest way to stub / mock / bypass the validation when we just want to generate a Factory(:url) for any other test, and to validate in the context of a sequential Url#url and Url#some_value.

For example, is there a way to generate FakeWeb requests in relation to each Factory(:url) instance (in principle it might read as follows);

Factory.define :url do |f|
  f.sequence(:url) { |n| "http://website#{n}.com" }
  f.some_value { |n| "{n}" }
  FakeWeb.register_uri(:get, url.url, :body => "<body>#{url.some_value}</body>")
end

Or, is it possible to stub the call to the validation, or the Hpricot method, except for when we're testing the validation in question?

Last edited by Neil (2010-04-30 15:23:31)

Re: Stubbing / mocking a call to a URL

A validation talking to the network is unusual. You already discovered that testing is painful. It also means that records in the database can become invalid when something out of the application scope changes.

If you want to continue down this path you could stub whatever mechanism you're using to GET those URLs in your test helper. Or implement a static switch in the Url-class that disables the validation when flipped.