3

テスト スイートで外部 API 呼び出しをスタブしようとしていますが、before(:suite) が実行されません。Webmock は、テストがまだ実行されていない場合でも、maps.googleapis.com をスタブ化する必要があることを常に報告します (緑色の点も赤色の F もありません)。

spec_helper.rb:

require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)

...

config.before(:suite) do
    puts "THIS NEVER SHOWS"
    stub_request(:get, "maps.googleapis.com").
      with(headers: {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
      to_return(status: 200, body: "", headers: {})
end

ジオコーダー gem は googleapis.com から緯度/経度を保存しようとし、URL が登録されていないことを示すエラーが Webmock によって発生します。

編集: エラー スニペット:

$ bundle exec rspec spec/factories_spec.rb
/home/jake/.rvm/gems/ruby-2.1.0@global/gems/webmock-1.17.4/lib/webmock/http_lib_adapters/net_http.rb:114:in `request': Real HTTP connections are disabled. Unregistered request: GET http://maps.googleapis.com/maps/api/geocode/json?address=[private]&language=en&sensor=false with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'} (WebMock::NetConnectNotAllowedError)

You can stub this request with the following snippet:

stub_request(:get, "http://maps.googleapis.com/maps/api/geocode/json?address=[private]&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 => {})

============================================================
    from /home/jake/.rvm/gems/ruby-2.1.0@global/gems/geocoder-1.1.9...

    ...

繰り返しますが、これは config.before(:each) ブロック内のコードが実行されないという事実に関係していることを強調します。なんで?もしそうなら、「'WTF' を上げる」ことができ、上記のエラーの代わりに 'WTF' がコンソール出力に表示されるはずです。Webmock gem を「バンドル解除」したときにのみ「WTF」が表示されます。

4

1 に答える 1

1

Factory がファイルの属性を持っているかどうかに応じて実行時にテストを作成することで、RSpec テストで「かわいいこと」をしていました。私のファクトリ/モデルのセットアップ方法が原因で、特定のファクトリの属性が読み取られるときにファクトリが作成 (保存) されたため、テストを生成するコードのブロックは RSpec の config.before(:suite) の外で実行されます。 WebMock でエラーが発生します。

https://github.com/bblimke/webmock/issues/378

さらに、これは特に私が間違っていたことです-WebMockとは関係ありません:

1) 私の factory.rb では、まだ存在していない可能性のある関連付けに対して create() を呼び出していました。なんで?RSpec が「[association] was blank」というエラーを表示していたためです。:association だけでなく、validates_presence_of :association_id があったため、それを行っていました。build() の代わりに create() を使用すると、「機能しました」。もちろん、WebMock を使用するようになったとき、ジオコーダーを呼び出すオブジェクトを作成 (および保存) していました。解決策は、適切な属性を使用するように validates_presence_of を修正し、工場で create() の代わりに build() を使用することでした。

悪い例:

# In spec/factories.rb
factory :review, class: Manager::Review do
    rating 4
    wine { Manager::Wine.first || create(:wine) }
    reviewer { Manager::Reviewer.first || create(:reviewer) }
    date Time.now
    association :referral, referrable_id: 1, referrable_type: Manager::Review, strategy: :build
end

# In app/models/manager/review.rb
validates_presence_of :rating_id, :wine_id, :reviewer_id, :date

良い例え:

# In spec/factories.rb
factory :review, class: Manager::Review do
    rating 4
    wine { Manager::Wine.first || build(:wine) }
    reviewer { Manager::Reviewer.first || build(:reviewer) }
    date Time.now
    association :referral, referrable_id: 1, referrable_type: Manager::Review, strategy: :build
end

# In app/models/manager/review.rb
validates_presence_of :rating, :wine, :reviewer, :date

2)FWIW、ジオコーダーに、ホームページで示唆されているような after_validate ではなく、ジオコード before_save を取得するように指示しました。

また、before(:suite) では WebMock でスタブできませんが、before(:each) では動作します。

于 2014-03-23T23:35:07.580 に答える