Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I mock an object in this case? no obvious way to replace object with mock

Suppose I have this very simple method in Store's model:

  def geocode_address
      loc = Store.geocode(address)
    self.lat = loc.lat
    self.lng = loc.lng
  end

If I want to write some test scripts that aren't affected by the geocoding service, which may be down, have limitations or depend on my internet connection, how do I mock out the geocoding service? If I could pass a geocoding object into the method, it would be easy, but I don't see how I could do it in this case.

Thanks!
Tristan

like image 321
WoodenKitty Avatar asked Feb 01 '11 23:02

WoodenKitty


People also ask

How do you mock an object in Python?

If you want to mock an object for the duration of your entire test function, you can use patch() as a function decorator. These functions are now in their own file, separate from their tests. Next, you'll re-create your tests in a file called tests.py .

How do you mock an object in JUnit?

We can use Mockito class mock() method to create a mock object of a given class or interface. This is the simplest way to mock an object. We are using JUnit 5 to write test cases in conjunction with Mockito to mock objects.


2 Answers

using rspecs built in mocking and stubbing, you could do something like this:

setup do
  @subject = MyClass.new
end

it 'handles geocoder success' do
  mock_geo = mock('result', :lat => 1, :lng => 1)

  Store.stub!(:geocode).and_return mock_geo

  @subject.geocode_address

  @subject.lat.should == mock_geo.lat
  @subject.lng.should == mock_geo.lng
end


it 'handles geocoder errors' do
  Store.stub!(:geocode).and_raise Exception

  @subject.geocode_address

  @subject.lat.should == _something_reasonable_
  @subject.lng.should == _something_reasonable_
end
like image 51
BaroqueBobcat Avatar answered Oct 02 '22 14:10

BaroqueBobcat


Using Double-R (RR) https://github.com/btakita/rr, it's simple:

test 'should mock the geocoding service' do
  store = Store.new

  mock_location = mock(Object.new)
  mock_location.lat{1.234}
  mock_location.lng{5.678}
  mock(Store).geocode.with_any_args{mock_location}

  store.geocode_address
  assert_equal 1.234, store.lat
  assert_equal 5.678, store.lng
end
like image 22
jemminger Avatar answered Oct 02 '22 14:10

jemminger