ruby-on-railsamazon-web-servicestestingamazon-s3aws-sdk-ruby

Stubbing AWS S3 object request


I'm trying to stub out a request to get an object in a AWS bucket. I've read their docs about stubbing requests and was only able to stub out a bucket, not an object. Here are somethings I've tried:

Stubbing through the AWS config:

Aws.config[:s3] = {
  stub_responses: {
    list_buckets: {
      buckets: [name: "my-bucket"],
      list_objects: [key: "file.pdf"]
    }
  }
}

While that got the bucket, it did not give me the object. Calling s3.buckets would list the bucket, but s3.objects would be empty.

Stubbing through webmock gem:

tempfile = file_fixture('file.pdf').read
base_uri = Regexp.new "https://my-bucket.s3.us-west-1.amazonaws.
stub_request(:get, base_uri).to_return(status: 200, body: tempfile)

This still doesn't seem to work. Calling bucket.objects still returns an empty collection.

The code in my controller I want to test:

s3 = Aws::S3::Resource.new
bucket = s3.bucket("my-bucket")
@files = {}

bucket.objects.each do |item|
  @files[File.basename(item.key)] = item.presigned_url(:get)
end

The goal is I want to make sure my view shows the links to the objects in my @file variable and I want to test that link. Any help would be greatly appreciated! I'm new to developing with AWS S3 and googlge haven't been much help. I'm using the aws-sdk-s3 gem to work with AWS S3.


Solution

  • Figured it out. I also needed to stub out the #list_objects method in order to get the objects. The final stub would look something like this:

    Aws.config[:s3] = {
      stub_responses: {
        list_buckets: {
          buckets: [name: "my-bucket"]
        },
        list_objects: {
          contents: [{key: "mykey"}]
        },
        get_object: {
          body: file_fixture('file').read
        }
      }
    }
    

    Now if I do s3.buckets.first.objects.first I would get back the stubbed object.