13

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?

Eric M.
  • 5,399
  • 6
  • 41
  • 67
  • Could you post more info about your code please? For example, what is a.cover? I'm assuming that a is your object, and cover is the attribute containing the URI to the image? – hwrd Feb 09 '11 at 10:16
  • Also, what exactly are you trying to test? It would help to have more context here. – hwrd Feb 09 '11 at 10:17

8 Answers8

7

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.

denishaskin
  • 3,305
  • 3
  • 24
  • 33
6

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

Anand Soni
  • 5,070
  • 11
  • 50
  • 101
5

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")
jbk
  • 1,911
  • 19
  • 36
3

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.

Dave Collins
  • 1,077
  • 1
  • 15
  • 23
  • I started with your idea, and then, reading [the v2 documentation for the `Aws::Client` class](http://docs.aws.amazon.com/sdkforruby/api/Aws/ClientStubs.html) decided that this works better: `Aws.config = {stub_responses: true}` – sameers Dec 23 '16 at 00:55
3

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

Eliza Brock Marcum
  • 1,570
  • 1
  • 14
  • 25
  • @Eric M. What code did you add to actually make this work? I'm having the same problem – Peter Nixey Nov 02 '11 at 12:46
  • @Eric M. @Eliza @Peter Nixey Was there a straightforward solution to this problem? I have tried various strategies include to `Paperclip::Shoulda` at various stages with no luck. Any follow-on suggestions? – sorens Mar 02 '13 at 15:46
  • @sorens - no idea I'm afraid. I moved on from this – Peter Nixey Mar 08 '13 at 15:08
1

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.

1

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.

Chris Gunther
  • 339
  • 1
  • 1
1

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
brutuscat
  • 3,139
  • 2
  • 28
  • 33