気ままに気ままのエンジニアブログ

定期的に得た知見を気ままに発信中

【Rails】VCRでハマったエラー「VCR::Errors::UnhandledHTTPRequestError:」の解決方法

こんにちは。

この世の匂いの中で一番好き!と言っても過言でない金木犀
ついに金木犀の香りミストを購入してしまいました。
家に振りまいてやろうと思います。

どうもハチマキです。

はじめに

今回VCRを使った際のエラーに結構ハマってしまいました。
エラー解決を見つけるのに時間がかかったため、今回はこのエラーの解決方法に関して記載していきます。

では早速行きましょう!

本日の概要 : VCR::Errors::UnhandledHTTPRequestError:の解決方法

VCRとは?

テストで使う『HTTP通信』を1回目に記録しておいて、2回目以降のテストでの実行時間を短縮し、効率的なテストを支援してくれるGemです。
具体的に言うと、テスト中に過去に投げたリクエストをカセット(cassete)に記録しておいて、その後再度同じリクエストが投げれられた場合はサーバーではなく、記録しておいたカセットからリクエストの結果を取り出すというものです。

事象

Rspecテストで、別のDBレコードを取得する必要がありVCRのGemを使用しました。
今回は、外部APIとのやりとり情報をテキスト情報で保存して、それをテスト内で読み込みたいがエラーが発生。。。

エラー例

1) testが通ること
     Failure/Error:~~
     
     VCR::Errors::UnhandledHTTPRequestError:

       ================================================================================
       An HTTP request has been made that VCR does not know how to handle:
         GET http://~~
     
       VCR is currently using the following cassette:
         - /Users/アプリ名/spec/vcr/features/~~.yml
         - :record => :once
         - :match_requests_on => [:method, :uri]
     
       Under the current configuration VCR can not find a suitable HTTP interaction
       to replay and is prevented from recording new requests. There are a few ways
       you can deal with this:
     
         * If you're surprised VCR is raising this error
           and want insight about how VCR attempted to handle the request,
           you can use the debug_logger configuration option to log more details [1].
         * You can use the :new_episodes record mode to allow VCR to
           record this new request to the existing cassette [2].
         * If you want VCR to ignore this request (and others like it), you can
           set an `ignore_request` callback [3].
         * The current record mode (:once) does not allow new requests to be recorded
           to a previously recorded cassette. You can delete the cassette file and re-run
           your tests to allow the cassette to be recorded with this request [4].
         * The cassette contains 1 HTTP interaction that has not been
           played back. If your request is non-deterministic, you may need to
           change your :match_requests_on cassette option to be more lenient
           or use a custom request matcher to allow it to match [5].
     
       [1] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/configuration/debug-logging
       [2] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/record-modes/new-episodes
       [3] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/configuration/ignore-request
       [4] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/record-modes/once
       [5] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/request-matching
       ================================================================================

原因

今回問題だったのは、VCR is currently using the following cassette:でした。
いわゆるカセットファイル(yml)にすでに同様のファイルが記憶されていたため、エラーが発生しました。
(過去に同様のカセットファイル名でコマンドを実行していたため、記憶されていたのでしょう。)

※定義しているカセットファイル(yml)がないか検索してみましょう。

解決方法

すでに記憶(存在)しているカセットファイル(yml)を削除します。

$ rm spec/vcr/features/~~yml 

これで再度テスト実行したらエラーが解消してました。
ファイルの内容を再度変更したい場合は、作成されているカセットファイルを削除し、再度テスト実行すると新しいカセットファイルが作成されます。