Skip to content

Instantly share code, notes, and snippets.

@nicolasrouanne
Forked from glittershark/mock_geocoder.rb
Last active March 5, 2018 09:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicolasrouanne/267d227be26b9819d0c7ca17bd3e8863 to your computer and use it in GitHub Desktop.
Save nicolasrouanne/267d227be26b9819d0c7ca17bd3e8863 to your computer and use it in GitHub Desktop.
Mock geocoding in Rspec, with _specifics for `Google Geocoding API`
# In spec_helper:
# RSpec.configure do |config|
# ...
# config.include(MockGeocoder)
# end
#
# In your tests:
# it 'mock geocoding' do
# # You may pass additional params to override defaults
# # (i.e. :coordinates => [10, 20])
# # NB: the results from `#data` won't be changed though (not implemented)
# mock_geocoding!
# address = Factory(:address)
# address.lat.should eq(1)
# address.lng.should eq(2)
# end
#
require 'geocoder/results/base'
module MockGeocoder
def self.included(base)
base.before :each do
allow(::Geocoder).to receive(:search).and_raise(
RuntimeError.new('Use "mock_geocoding!" method in your tests.')
)
end
end
def mock_geocoding!(options = {})
# Sample data attribute which contains the complete response of Google API
# > "...call the #data method of any Geocoder::Result object to get the full parsed response."
# @link https://github.com/alexreisner/geocoder#advanced-geocoding
mock_data = {
"address_components" => [
{ "long_name" => "Marseille", "short_name" => "Marseille", "types" => %w[locality political] },
{ "long_name" => "Bouches-du-Rhône", "short_name" => "Bouches-du-Rhône", "types" => %w[administrative_area_level_2 political] },
{ "long_name" => "Provence-Alpes-Côte d'Azur", "short_name" => "Provence-Alpes-Côte d'Azur", "types" => %w[administrative_area_level_1 political] },
{ "long_name" => "France", "short_name" => "FR", "types" => %w[country political] }
],
"formatted_address" => "Marseille, France",
"geometry" => {
"bounds" => {
"northeast" => { "lat" => 43.3911601, "lng" => 5.5323519 },
"southwest" => { "lat" => 43.169621, "lng" => 5.228641 }
},
"location" => { "lat" => 43.296482, "lng" => 5.36978 },
"location_type" => "APPROXIMATE",
"viewport" => { "northeast" => { "lat" => 43.3911601, "lng" => 5.5323519 }, "southwest" => { "lat" => 43.169621, "lng" => 5.228641 } }
},
"place_id" => "ChIJM1PaREO_yRIRIAKX_aUZCAQ",
"types" => %w[locality political]
}
options.reverse_merge!(address: "Marseille, France",
coordinates: [43.296482, 5.36978],
state: "Provence-Alpes-Côte d'Azur",
state_code: "Provence-Alpes-Côte d'Azur",
country: "France",
country_code: "FR",
'address_components': {
'types': %w[locality political],
'long_name': "Marseille",
'short_name': "Marseille"
})
MockResult.new(mock_data).tap do |result|
options.each do |prop, val|
allow(result).to receive(prop).and_return(val)
end
allow(Geocoder).to receive(:search).and_return([result])
end
end
class MockResult < ::Geocoder::Result::Google
def initialize(data = [])
super(data)
end
end
end
RSpec.configure do |config|
config.include MockGeocoder
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment