Stubbing Paperclip S3 requests in specs

6.4k views Asked by At

I am using Paperclip and S3 for image uploads and am trying to stub out calls to S3 from my test suite. I found the thoughtbot post which mentions doing

  a.cover       { a.paperclip_fixture('album', 'cover', 'png') }

but that gives me a "wrong number of arguments (4 for 2)" error. I tried switching the arguments above to an array, which removes the original error, but gives an error saying "Attribute already defined: paperclip_fixture".

Has anyone been able to get this working? Also, I'd ideally like to use the local filesystem for the development environment. Is there an easy way to do this?

8

There are 8 answers

3
Eliza Brock Marcum On BEST ANSWER

Are you using shoulda? If you aren't using shoulda the paperclip_fixture method that you're using may come from somewhere else and thus behave differently.

Potentially relevant: https://github.com/thoughtbot/paperclip/blob/master/shoulda_macros/paperclip.rb

0
brutuscat On

This is how I got this working. First you have to have the fakeweb gem or it will fail. You also have to have an empty file in the spec/support/paperclip/[model]/[attachment_name][ext] path.

What I did was to copy the code from Paperclip and paste it into my factory. I was unable to get the 'paperclip_fixture' working.

factory :attachment do
  file do |a|
    # Stubbed  Paperclip attachment from: https://github.com/thoughtbot/paperclip/blob/master/shoulda_macros/paperclip.rb#L68
    # FIX: This was the only way I made this work. Calling the paperclip_fixture directly didn't work.
    # See: http://stackoverflow.com/questions/4941586/stubbing-paperclip-s3-requests-in-specs
    model, attachment, extension = "customer_attachment", "file", "doc"      
    definition = model.gsub(" ", "_").classify.constantize.
                       attachment_definitions[attachment.to_sym]

    path = "http://s3.amazonaws.com/:id/#{definition[:path]}"
    path.gsub!(/:([^\/\.]+)/) do |match|
      "([^\/\.]+)"
    end

    begin
      FakeWeb.register_uri(:put, Regexp.new(path), :body => "OK")
    rescue NameError
      raise NameError, "the stub_paperclip_s3 shoulda macro requires the fakeweb gem."
    end
    base_path = File.join(Rails.root, "spec", "support", "paperclip")
    File.new(File.join(base_path, model, "#{attachment}.#{extension}"))
  end
end
0
Anand Soni On

With latest paperclip(from github master branch) and aws-sdk version 2, I solved my issue with following configuration :

require "aws-sdk"
Aws.config[:s3] = {stub_responses: true}

For more information, please take a look at amazon sdk

0
denishaskin On

Okay, I've got the basic issue figured out. This is (I believe) as Eliza said, because I'm not using shoulda (I'm using rspec 2.6.0 and factory_girl 2.1.2).

Here's what worked for me (where Profile is the class that has attachements):

  Profile.any_instance.stub(:save_attached_files).and_return(true)
  @profile = Factory(:profile)

At the moment I just have this right in my before method of my rspec example. There's probably a better place to put it.

1
Dave Collins On

Many of these techniques don't seem to work with the latest paperclip and S3. What finally worked for me is the combination of:

AWS.config(:access_key_id => "TESTKEY", :secret_access_key => "TESTSECRET", :stub_requests => true)

and

Mymodel.any_instance.stubs(:save_attached_files).returns(true)

But, actually, all you really need to do in many cases is the AWS :stub_requests and it will achieve what you want.

0
jbk On

Placing this in my 'spec/rails_helper.rb' file worked for me:

require 'aws'
AWS.stub!
AWS.config(:access_key_id => "TESTKEY", :secret_access_key => "TESTSECRET")
0
Diego d'Ursel On

This is how I stub a file from paperclip without using the shoulda helpers.

before(:each) do 
  @sheet = double('sheet')
  @sheet.stub(:url).and_return(File.join(Rails.root, 'spec','fixtures','files', 'file.xls'))
  active_record_object.stub(:sheet).and_return(@sheet)
end

Hope this helps someone.

0
Chris Gunther On

I just came across this upgrading an app from Rails 2.3 to Rails 3.0 after having followed Testing Paperclip on S3 with Cucumber & Factory Girl.

Instead of including the Paperclip::Shoulda module into the Factory class, I had to include it into the FactoryGirl::DefinitionProxy class, so I changed this:

class Factory
  include Paperclip::Shoulda
end

to

class FactoryGirl::DefinitionProxy
  include Paperclip::Shoulda
end

For reference, I'm using paperclip 2.4.1 and factory_girl 2.0.5.