title: How to properly mock objects in RSpec?
body: <p>I have a simple class, which generates a download URL to a file stored on S3 and I need to write a unit test to test this class. So far I've had no luck.</p>
  
  <pre><code>class S3DownloadUrlGenerator
    def initialize(filename)
      @filename = filename
    end
  
    def presigned_url
      signer = Aws::S3::Presigner.new(client: s3)
      signer.presigned_url(
        :get_object,
        bucket: "my-bucket",
        key: filename,
        response_content_disposition: "attachment",
      )
    end
  
    private
  
    def s3
      @s3 ||= Aws::S3::Client.new(
        region: "my-region,
        http_open_timeout: 5,
        http_read_timeout: 25,
      )
    end
  
    attr_reader :filename
  end
  </code></pre>
  
  <p>I want to test if calling #presigned_url on an instance of S3DownloadUrlGenerator returns a URL.
  This is my test:</p>
  
  <pre><code>describe S3DownloadUrlGenerator do
    before do
      allow(Aws::S3::Client).to receive(:new) { s3_client }
    end
    let(:s3_client) { spy("s3 client") }
    let(:presigner) { spy("s3 presigner") }
  
    it "generates download URL for a file" do
      expect(Aws::S3::Presigner).to receive(:new).with(client: s3_client).and_return(presigner)
      expect(presigner).to receive(:presigned_url).with(
        :get_object,
        bucket: "my-test-bucket",
        key: "test_file.txt",
        response_content_disposition: "attachment",
      ).and_return("https://www.example.com")
      expect(described_class.new("Test_file.txt").presigned_url).to eq("https://www.example.com")
    end
  end
  </code></pre>
  
  <p>but I get an error:</p>
  
  <pre><code>Failure/Error: expect(described_class.new("Test_file.txt").presigned_url).to eq("https://www.example.com")
  
         expected: "https://www.example.com"
              got: #&lt;Double "s3 presigner"&gt;
  
         (compared using ==)
  </code></pre>
  
  <p>I am bit new to this and I would like to learn how to properly test such cases. Thank you very much for the help.</p>