12

私のキュウリサポートディレクトリでは、vcr.rbに次のものがあります。

require 'vcr'

VCR.configure do |c|
  c.cassette_library_dir = 'fixtures/vcr_cassettes'
  c.hook_into :webmock
  c.ignore_localhost = true
  c.default_cassette_options = { record: :new_episodes }
end

GoogleMapsAPIを呼び出す都市名をジオコーディングしています。これらのリクエストを記録してスタブしようとしていますが、同じymlファイルに同じリクエストを記録し続けます:

- request:
    method: get
    uri: http://maps.googleapis.com/maps/api/geocode/json?address=Miami,%20FL&language=en&sensor=false
    body:
      encoding: US-ASCII
      string: ''
    headers:
      Accept-Encoding:
      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
      Accept:
      - ! '*/*'
      User-Agent:
      - Ruby
  # response...

- request:
    method: get
    uri: http://maps.googleapis.com/maps/api/geocode/json?address=Miami,%20FL&language=en&sensor=false
    body:
      encoding: US-ASCII
      string: ''
    headers:
      Accept-Encoding:
      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
      Accept:
      - ! '*/*'
      User-Agent:
      - Ruby

これは同じURLでまったく同じリクエストですが、VCRはリクエストをスタブ化するべきではありませんか?同じ都市を検索しようとするたびにスペックがAPIにヒットしないようにするにはどうすればよいですか?

4

4 に答える 4

21

あなたが投稿したものだけで何が起こっているのかを確実に言うのは難しいですが、VCRがどのように機能するかについてもう少し説明し、この動作の考えられる理由についていくつか推測することができます。

VCRは、リクエストマッチャーを使用して、以前に記録されたHTTPインタラクションを見つけて再生しようとします。シングルカセットセッション中に、HTTPインタラクションが再生されると、「使用済み」と見なされ、再度再生されることはありません(allow_playback_repeatsオプションを使用しない限り)。

だから...ここに頭に浮かぶいくつかの可能性があります:

  • VCRがHTTPリクエストに一致しない可能性があります。どのリクエストマッチャーを使用していますか?これをトラブルシューティングする簡単な方法がいくつかあります(以下を参照)。
  • 使用していない場合:allow_playback_repeats(これはデフォルトであり、VCRの使用をお勧めします)、テストで複数の重複リクエストが行われている場合に表示される動作が発生する可能性があります。たとえば、カセットに1つしかない場合などです。一致するリクエストですが、テストでは2つ作成されます。1つを再生して1つを記録します(を使用しているため:new_episodes)。

これをトラブルシューティングするには、debug_loggerオプションを使用して、VCRに、VCRが実行していることと、各要求にどのように一致させようとしているのかを出力させることをお勧めします。それはあなたに何が起こっているかについての洞察を与えるはずです。組み込みのリクエストマッチャーをオーバーライドして、独自のロジックを提供したり、マッチャーにブレークポイントを設定したりすることもできます。

VCR.configure do |c|
  c.register_request_matcher :uri do |request_1, request_2|
    debugger # so you can inspect the requests here
    request_1.uri == request_2.uri
  end
end

また、VCRのバグに遭遇した可能性もありますが、URIの比較(を使用String#==)は非常に基本的な操作であるため、そこでバグを想像するのは困難です。理解できない場合は、githubの問題(できればデバッグロガーの出力やこれをトリガーするコードサンプルを使用して)を開いてください。

:onceちなみに、ではなく記録モード(デフォルト)を使用することをお勧めします:new_episodes:once既存のカセットに追加のHTTPインタラクションを記録することはありません。これにより、カセットを1回だけ記録できます。リクエストが一致しなかった場合、一致しなかったという事実を警告するエラーが発生します。 :new_episodes一方、一致するものが見つからないリクエストはすべて記録されます。これは、表示されている動作です。

于 2012-07-12T01:40:13.147 に答える
9

同様の問題が発生したときは、match_requests_on設定をより具体的にすることで修正しました。

VCR.configure do |c|
    c.default_cassette_options = {
        match_requests_on: [:uri, :body, :method]
    }
end
于 2014-02-14T19:18:24.167 に答える
2

私は同じような振る舞いを経験したので、私がしていることは基本的にに設定し続けること:noneです。新しいリクエストが発生した場合は、を使用して、リクエスト:anyを実行したテストスイートの一部を実行し、に戻し:noneます。

奇妙な:new_episodesヒューリスティックを使用して、新しいリクエストとは何か、すでに発生したリクエストは何かを判断しているようです。私たちの場合、ペイメントゲートウェイへの2つの異なるリクエストを同じものとしてマークし、デバッグに無限の時間を費やしました。これは、aなどRefundOkに対する回答が得られたためCaptureRequestです。使用しない方が良い:new_episodes...

于 2012-07-11T21:28:28.007 に答える
0

一致パラメーターを定義しない場合、VCRでElasticsearchを使用すると、常にカセットが再生成されます。一致を定義する必要があるのは、テストが実行されるたびにとが変更される可能性が:methodあるためです。:uri:body

VCR.configure do |c|
  c.hook_into :webmock
  c.ignore_localhost = true
  c.configure_rspec_metadata!
  c.cassette_library_dir = 'spec/cassettes'
  c.default_cassette_options = { record: :new_episodes,
                                 match_requests_on: [:method] }
end
于 2020-12-03T11:03:51.920 に答える