🌫️

Fog側をモックしたらCarrierWaveのUploaderインスタンスを作らずに済む話

2024/12/18に公開

はじめに

こんにちは。スペースマーケットでWebエンジニアしてます、新卒のdumbled0reです。

7月にチームに入ってから早5ヶ月が経ち、少しずつスクラム開発に慣れてきた今日この頃です。

今回はAWSやGCPなどのクラウドストレージにファイルをアップロードするときのテストでFog側をモックすれば、テスト時に毎回CarrierWaveのUploaderインスタンスを作成しなくても済むよというお話です。

CarrierWaveとFogの概要

CarrierWaveとは

CarrierWaveはRuby on Railsアプリケーションでファイルを簡単にアップロードできるライブラリです。ファイルの保存先としてローカルストレージやクラウドストレージ(S3など)を利用することができます。

Fogとは

Fogはさまざまなクラウドサービスを統一的に扱うためのライブラリです。AWS S3やGoogle Cloud Storageなどのストレージサービスにアクセスするためのインターフェースを提供します。

テストの問題点

クラウド上へのファイルアップロードを含むテストを書く際はRspecで以下のように書いていました。

allow_any_instance_of(CarrierWave::Uploader::Base).to receive(:store!).and_return(true)

上記のように書いてもファイルアップロード部分をモックできますが、同じコードを複数のテストで使うために繰り返し記述する必要があり、テストコードが冗長になってしまいます。

そこで、fog側をモックするspec/support/fog.rbを作成しました。
※事前にrails_helper.rbにsupportディレクトリ配下のファイルを読み込ませるようにしておきます。

spec/support/fog.rb
Fog.mock!
connection = Fog::Storage.new({
  provider: 'AWS',
  aws_access_key_id: ENV['AWS_WEB_ACCESS_KEY_ID'],
  aws_secret_access_key: ENV['AWS_WEB_ACCESS_KEY_SECRET'],
  region: ENV['AWS_DEFAULT_REGION']
})
connection.directories.create(:key => ENV['AWS_S3_BUCKET'])

Fog.mock!で仮想ストレージを使用することで、テスト時に実際のクラウドストレージを操作せずに、アップロード処理が正しく動作するかを確認できます。
これで、毎回CarrierWaveのUploaderインスタンスをモックする必要がなくなり、テストコードが冗長になることを防ぐことができました。

補足

仮想ストレージを作成している各引数の値は以下のイシューに言及されてある通り、実際のCarrierWaveに設定している値ではないとテストがコケてしまいました。

connection = Fog::Storage.new({
  provider: 'AWS',
  aws_access_key_id: ENV['AWS_WEB_ACCESS_KEY_ID'],
  aws_secret_access_key: ENV['AWS_WEB_ACCESS_KEY_SECRET'],
  region: ENV['AWS_DEFAULT_REGION']
})
connection.directories.create(:key => ENV['AWS_S3_BUCKET'])

https://github.com/fog/fog/issues/3895

Fixed this. It turns out that the access key and secret used for the mock storage should be the same used in carrierwave config otherwise the mis-match causes it to fail

意訳: モックストレージで使用するアクセスキーとシークレットはCarrierWaveの設定で使用されるものと同じでなければならない

検証

使用しているcarrierwavefog-awsのバージョンが古いせいでエラーが発生しているのか検証するため、下記のバージョンでも試してみましたが、同様のエラーが発生しました。

  • ruby 3.2.6
  • carrierwave 3.1.0
  • fog-aws 3.28.0

さいごに

スペースマーケットでは一緒にサービスを成長させていく仲間を探しています!
新卒でもフロントエンドやバックエンドに関わることでき、成長できる環境があります。
ご興味ある方はこちらからご応募お待ちしております!

スペースマーケット Engineer Blog

Discussion