How do I make fun of an object in this case? there is no obvious way to replace the object with a breadboard

Suppose I have this very simple method in a Store 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 are not affected by the geocoding service, which may not be available, have limitations, or depend on my Internet connection, how do I mock the geocoding service? If I could pass the geocoding object to this method, that would be easy, but I don’t see how to do this in this case.

Thanks!
Tristan

+4
source share
3 answers

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 
+2
source

Using rspecs built into mockery and stubbing, you can 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 
+8
source

If there is no way to mock the service, it shows a poor design. The service must be separate from the model (regardless of Store ). You just need to reorganize the system with more decompensation, which will allow you to mock it and simplify its work.

0
source

Source: https://habr.com/ru/post/1338020/


All Articles