🛤️

[ruby] Aws::S3::Clientのput_objectをrspecで実装する

2024/08/14に公開

概要

railsで実装されているawsのrspecが書いてなかったので、rspecを書こうとしたら情報がなさすぎて苦戦したので、記載方法を残しておきます。

環境

  • ruby 3.3.4
  • rails 7.1.3
  • aws-sdk 3.2.0

テストコードの書き方

stubの書き方は2通りあります。

一つ目は

aws = Aws::S3::Client.new(stub_responses: true)

のようにオブジェクトでstub_responsesを指定する方法

もう一つは

Aws.config[:s3] = {
  stub_responses: {
    list_buckets: { buckets: [{name: 'my-bucket' }] }
  }
}

のようにデフォルトのスタブをAws.configで設定する方法です。

ネットに溢れている情報は前者のオブジェクトをスタブ化する方法がほとんどですが、この方法ではcontrollerなどでテストを通すことができません。

なので、どちらでも利用できる後者のやり方で実装するべきです。

デフォルトのスタブ

デフォルトのスタブはAws.configで設定できます。

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ClientStubs.html

Aws.config[:s3] = {
  stub_responses: {
    list_buckets: { buckets: [{name: 'my-bucket' }] }
  }
}

デフォルトのスタブでput_objectのテスト

put_objectはs3にファイルをuploadするのに利用します。

スタブは以下のように記載します。

Aws.config[:s3] = {
  stub_responses: {
    put_object: {
      etag: '1234567890abcdef0', # ETag
    }
  }
}

テスト対象のコードは以下です。

res = Aws::S3::Client.new.put_object(
  bucket: "test",
  key: "test",
  body: "test"
)
puts res[:etag] #'1234567890abcdef0'

res[:etag]で'1234567890abcdef0'が返却されます。

オブジェクトのスタブでput_objectのテスト

こちらは、webでよく見るテストコードの書き方です。

正直あまり役に立つとは思えません。

s3 = Aws::S3::Client.new(stub_responses: true)
s3.stub_responses(:put_object, -> (context) {
  s3.stub_responses(:get_object, content_type: context.params[:content_type])
})
puts s3.put_object(bucket: "test", key: "test", body: "Doesn't matter")

上記でetag等を含むhashを取得することができます。

まとめ

クラウドサービスを使った部分のテストコードが書かれないまま放置されているケースをよく見かけます。

google cloudのライブラリのようにallow_any_instance_ofを使って完全にスタブ化するしかないケースもありますが、多くのライブラリではunit test用の仕組みが用意されていることが多いです。

たいして調べもせず

「無理」

とあきらめないで、色々調べてなるべく多くのテストコードを書く習慣を身につけましょう。

Discussion