简体   繁体   中英

Trying to test (minitest) method that invokes AWS S3 Bucket copy_to. How to mock or stub?

We have an Attachment model with a copy_for_edit! method which helps an Attachment copy itself. The attachment data is stored in AWS S3 bucket(s). We make use of the Bucket copy_to technique to perform the copy remotely on the AWS S3 server, without transferring the data back to us. https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#copy_to-instance_method

I'm writing a unit test (in minitest) for this method, and getting this error caused by the Aws::S3::Bucket#copy_to instance method:

Aws::S3::Errors::NoSuchKey: Aws::S3::Errors::NoSuchKey: The specified key does not exist.

I've seen countless solutions for how to stub an AWS S3 Client, but not a Bucket. I'm sure I'm missing something simple here. The code itself works in staging and production, but testing in my development environment I'd obviously prefer not to hit the AWS S3 server. But even if I configure the test environment to use our staging credentials for the bucket, that doesn't work either (same error).

I'd like to know how to stub (or similar) the Aws::S3::Bucket#copy_to instance method in minitest.

I know I've left out some details. I will be watching this closely and editing to add context if needed.

Edit 1: A simplified version of the test looks like this:

test '#copy_for_edit! should copy the attachment, excluding some attributes' do
  source = attachments(:attachment_simple)  #From an existing fixture.
  result = nil

  assert_difference(-> { Attachment.count }, 1) do
    result = source.copy_for_edit!
  end

  assert_nil(result.owner)
  assert_nil(result.draft_id)
end

Narrowing it down to an instance method (not a class method or attribute) helped me narrow down my options. I finally got the syntax correct, and believe I have a working test now.

This was basically my solution: https://stackoverflow.com/a/29042835/14837782

I can't say I've stubbed the AWS S3 Bucket#copy_to method. I've actually just stubbed our own method ( copy_attached_file_to ) that eventually calls it, since I'm not actually testing that method. When it comes time to test that method, I might be in similar trouble. Although maybe this solution will work to stub Bucket similarly.

And here is the test now, seemingly working properly:

  test '#copy_for_edit! should copy the attachment, excluding some attributes' do

    source = attachments(:attachment_simple)  #From an existing fixture.
    source.stub(:copy_attached_file_to, true) do
      result = nil

      assert_difference(-> { Attachment.count }, 1) do
        result = source.copy_for_edit!
      end

      assert_nil(result.owner)
      assert_nil(result.draft_id)
    end
  end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM