Rails
gmaps4rails

gmaps4railsのmockの作成の仕方

 gmaps4railsでのrsepc

gmaps4railsは住所からgeocodeを特定のし、google_mapを表示出来るgemである

gem "gmaps4rails"
gem "geocoder"

しかし、テスト(rspec)を書いていくと

 WebMock::NetConnectNotAllowedError:
       Real HTTP connections are disabled. Unregistered request: GET http://maps.googleapis.com/maps/api/geocode/json?address=%5B%22%E3%80%92222-0033%22%5D&language=en&sensor=false with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}

       You can stub this request with the following snippet:

       stub_request(:get, "http://maps.googleapis.com/maps/api/geocode/json?address=%5B%22%E3%80%92222-0033%22%5D&language=en&sensor=false").
         with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
         to_return(status: 200, body: "", headers: {})

→要はテストでは実際にhttpアクセスを使えないよとの事。
gem内で住所を取得するために、API通信をしているためだ。

対応方法

webmockを入れます。
→dummy_request的な事ができます。

gem 'webmock'

下記のような感じで、createするまえに、stubを登録してあげることで
実際のAPIアクセスではなく、dummyのレスポンスが返ってきます。

spec/factories/places.rb
require 'webmock'

FactoryBot.define do
  factory :place do
    sequence(:name) { |i| "会場名#{i}" }
    address { 
      %w(
      〒102-8321 東京都千代田区北の丸公園2−3
      〒222-0033 神奈川県横浜市港北区新横浜3丁目10番地
      〒540-0002 大阪府大阪市中央区大阪城3番1号
      ).sample(1)
    }

    before :create do |place| 
      WebMock.allow_net_connect!(:net_http_connect_on_start => true)
      WebMock.enable!
      WebMock.stub_request(:get, "http://freegeoip.net/json/76.24.18.47").
      with(:headers => {'Accept'=>'*/*',
        'User-Agent'=>'Ruby'}).
      to_return(:status => 200,
        :body => '{
          "ip":"76.24.18.47",
          "country_code":"US",
          "country_name":"United States",
          "region_code":"MA",
          "region_name":"Massachusetts",
          "city":"Cambridge",
          "zipcode":"02138",
          "latitude":42.38,
          "longitude":-71.1329,
          "metro_code":"506",
          "area_code":"617"}',
        :headers => {}
      )
    end

  end
end