RSpecでAWS S3の通信をstubする

今回やりたかったこと

RSpecでのテストで外部との通信があるとタイムアウトだったり、特定のタイミングでテストが通らなかったりするので擬似的にテストを行った。

コード


describe '*******' do  
  let(:fake_s3) { {} }
  let(:client) do
    client = Aws::S3::Client.new(stub_responses: true)
    client.stub_responses(
      :create_bucket, ->(context) {
        name = context.params[:bucket]
        if fake_s3[name]
          'BucketAlreadyExists' # standalone strings are treated as exceptions
        else
          fake_s3[name] = {}
          {}
        end
      }
    )
    client.stub_responses(
      :get_object, ->(context) {
        bucket = context.params[:bucket]
        key = context.params[:key]
        b_contents = fake_s3[bucket]
        if b_contents
          obj = b_contents[key]
          if obj
            { body: obj }
          else
            'NoSuchKey'
          end
        else
          'NoSuchBucket'
        end
      }
    )
    client
  end
  before do
     client.create_bucket(bucket: bucket_name)
      allow(Aws::S3::Client).to receive(:new).and_return(client)
  end
end


これでAws::S3::Clientがstub先を見るようになって解決。

参考

https://aws.amazon.com/jp/blogs/developer/advanced-client-stubbing-in-the-aws-sdk-for-ruby-version-3/
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ClientStubs.html