概要
VCRを使ったことがなく、かなりハマってしまったので、自分用にメモ
インストール方法などは他に山ほど記事があるので、そちらを参照してください。
前提
- request spec
- APIのテストではなく、request specでテストしたいアクション内でAPIを呼び出しており、そのAPIをstubしたい
stubされているかどうかの確認
他の方が書いてくださったものを拝借
spec_helper.rbに以下を記載
VCR.configure do | c |
...
# ここから
[ "recordable", "stubbed" ].each do | method |
c.after_http_request("#{method}?".to_sym) do | request, _response |
puts "- VCR - #{method} - [#{request.method}] #{request.parsed_uri}"
unless request.externally_stubbed?
puts " used cassette - #{VCR.current_cassette.try(:file)}"
else
puts " stubbed by WebMock"
end
end
end
# ここまで追加
end
以下のような表示がされるので、以降のテストの確認に便利
- VCR - recordable(stubされている場合はstubbed) - [get] http://test.com/ # 自分のアプリのURL
used cassette - /myapp/spec/fixtures/vcr/test.yml # なんのcassetteを利用しているか
参照: https://qiita.com/choripon/items/bb4c7aa9ce7f6cfa62a1
動的なパラメータがある場合のcassetteのマッチング
ネットで見た
match_requests_on: [:method, VCR.request_matchers.uri_without_params(:signature, :timestamp)]
はなぜか自分の環境だとうまいこといかなかった…
(自分の記述が悪い可能性大)
ので、代わりに以下を利用した。
match_requests_on: [:host, :path]
動的にcassetteの内容を変更する
ymlにはerbを埋め込めるので、yml側にerbを埋め込み
body:
encoding: UTF-8
string: |-
[
{
"id": "1",
"user_name": <%= "#{user_name}" %> # ここを埋め込む
}
]
# erb: { [erb側で指定したキー]: [値] }という形でuse_cassetteメソッドに渡す
VCR.use_cassette('test', match_requests_on: [:host, :path], erb: { user_name: user.name }) do
get test_index_path
end
ハマりポイント
ymlの値を
[
{
"id": 1,
"user_name": <%= user_name %>
}
]
こんな感じで定義するとHerがパースできなかったので、値、キーともに"
で括らないとダメだった。
(特に埋め込んでもちゃんとやらないとだめ)