RSpecでWebMockを有効にしているけれど、関心事から外れているケースでAPIレスポンスのスタブを書きたくないということはあると思います。そのようなとき、RSpecのinstance_double1 を使ってロジック目線でモック・スタブを書ける場合があります2。
# Shrine: Ruby向けファイルアップローダ https://github.com/shrinerb/shrine
def stub_shrine!
# 最初はこれだけ書く
uploader = instance_double('Shrine')
uploaded_file = instance_double('Shrine::UploadedFile')
allow(Shrine).to receive(:new).and_return(uploader)
allow(Shrine).to receive(:uploaded_file).and_return(uploaded_file)
# RSpecを実行しながら都度追記する
allow(uploader).to receive(:upload).and_return(uploaded_file)
allow(uploaded_file).to receive(:is_a?).with(Shrine::UploadedFile).and_return(true)
allow(uploaded_file).to receive(:data).and_return('data')
allow(uploaded_file).to receive(:size).and_return(1)
allow(uploaded_file).to receive(:mime_type).and_return('image/jpeg')
allow(uploaded_file).to receive(:extension).and_return('jpeg')
allow(uploaded_file).to receive(:storage_key).and_return('key')
allow(uploaded_file).to receive(:url).and_return('url')
end
下記のようなメリットがあると思います。
- 最初の数行さえ書けば、あとはRSpecに指摘された部分を追記していくだけでよい
- コードベース上に、ロジック目線の知識が増える。思わぬ不具合(誤った想定)に気づけることも
もちろん、具体的なAPIレスポンスが関心事に含まれるケースがあれば(あるはずだと思います)、そちらではWebMockでAPIレスポンスのスタブを書くべきです。
例示コードの動作バージョン:
rspec-rails (5.1.2)
shrine (3.4.0)
- メソッドが存在しているかどうかを検証できるdouble。https://rspec.info/features/3-13/rspec-mocks/verifying-doubles/instance-doubles/ ↩︎
- 外部依存先にテスト用のモック・スタブが用意されていることも多いので、先に調べた方が良い。例えばRailsにおける現在時刻なら
ActiveSupport::Testing::TimeHelpers
。GeocoderならGeocoder::Lookup::Test
。 ↩︎
コメント