Feb 12 paperclip attachments testing for the whole battery: RSpec and Cucumber

tags: paperclip rspec cucumber | comments

Paperclip is my favourite choice for attachments, and today I needed to spec and cuke my attachments. Even though there are ways to speed your attachments tests I prefer simple, and usable all over. The trick is to create a test attachment and attach it to your models.

Dummy attachments support for RSpec and Cucumber

We want it simple:

# in your specs or cucumber steps, of course object should be using paperclip and such
attach_dummy_to object

So let’s create the dummy attachment. Touching will do:

$ touch spec/fixtures/test.attachment

Then create a support file for your specs:

# spec/support/dummy_attachments.rb
module DummyAttachments
  # I made inside a module to include it in cucumber World
  def attach_dummy_to(object)
    dummy_attach = File.new(File.join(Rails.root, 'spec/', 'fixtures',
                                      'test.attachment'))

    object.attachment = dummy_attach
    object.save!
  end
end

Then require it, for rspec is:

# spec/spec_helper.rb
Dir[File.dirname(__FILE__) + '/support/*.rb'].each {|file| require file}

# in your spec/blueprints.rb
require File.expand_path(File.dirname(__FILE__) + '/support/dummy_attachments')
include DummyAttachments

and for cucumber also:

# features/support/my_env.rb
require File.expand_path(File.dirname(__FILE__) + '/../../spec/support/dummy_attachments')
World(DummyAttachments)

This way you’ll be actually using a real attachment, no stubs or nothing. But if you only need to stub the attachment is there (for speed you know) then:

@object.attachment.stub!(:exists?).and_return(true)
# that of course if you are relying on 
object.attachment.exists?

If you are wondering if blueprints.rb’s and World’s module inclusion will be collapsing, well they do and don’t. But it does looks like it could be dried up, but that for the next episode I guess :-)

Update

I was trying to repeat this myself in another project by reading this post and had to spend some time rethinking how exactly was I doing it in the end. So to clarify, actually I separated the module insides:

module DummyAttachments
  def attach_dummy_to(object)
    object.attachment = dummy_attach
    object.save!
  end

  def dummy_attach
    File.new(dummy_filename)
  end

  def dummy_filename
    File.join(Rails.root, 'spec/', 'fixtures', 'test.attachment')
  end
end

then in the blueprints is fairly easy to do:

Document.blueprint do
  attachment { dummy_attach } # this is paperclip magic :-)
end

I hope it’s clearer now :-)

blog comments powered by Disqus