Yesterday I wanted to mock this method:
class HtmlFromUrl
def get_page
#download page from web
...
end
end
It gets called here (in HtmlFromUrl.new):
class WebPage
def html
@html ||= HtmlFromUrl.new(url)
end
end
I didn’t want to use a traditional mock object. I want to test that an object of the correct class was created in the ‘html’ method (this method is actually much more complicated than what is shown above) but I didn’t want to actually download a page from the web. This is the way I ended up doing this:
Object.mock(HtmlFromUrl, :get_page, %Q{"<html><head/><body><p>content</p></body></html>"})
and later
Object.unmock
This is the basis of the mock method
class Class
def mock(klass, method_name, new_method_body)
mock_class = Class.new(klass)
mock_class.class_eval(%Q{
def #{method_name.to_s}(*args)
#{new_method_body}
end})
set_constant(klass.name, mock_class)
end
end
The creates a new anonymous class that inherits from the class we wish to mock, defines the method that we want to mock and sets the old class constant name to refer to the new class. Seems to work pretty well, code and tests here