---
title: Testing Paperclip with Shoulda
teaser:
tags: web,ruby,testing,paperclip,shoulda
author: Tammer Saleh
published_on: 2008-06-03
---

[Josh Susser](http://blog.hasmanythrough.com/) had a bunch of great things to
say about [Shoulda](https://github.com/thoughtbot/shoulda) in his RailsConf
2008 presentation, [The great test framework
dance-off](http://blog.hasmanythrough.com/2008/6/1/the-great-test-framework-dance-off).
One of the parts he really liked was the conceptual simplicity of creating
macros when drying up your tests.

It’s a misnomer to even call what you do with Shoulda “macros”, since _they’re
just normal class methods_.  Here’s one we use all the time for our projects
that use [Paperclip](https://github.com/thoughtbot/shoulda) (which you should
definitely check out if you haven’t all ready).

```ruby
# in test_helper.rb...
class Test::Unit::TestCase
  def self.should_have_attached_file(attachment)
    klass = self.name.gsub(/Test$/, '').constantize

    context "To support a paperclip attachment named #{attachment}, #{klass}" do
      should_have_db_column("#{attachment}_file_name",    :type => :string)
      should_have_db_column("#{attachment}_content_type", :type => :string)
      should_have_db_column("#{attachment}_file_size",    :type => :integer)
    end

    should "have a paperclip attachment named ##{attachment}" do
      assert klass.new.respond_to?(attachment.to_sym),
              "@#{klass.name.underscore} doesn't have a paperclip field named #{attachment}"
      assert_equal Paperclip::Attachment, klass.new.send(attachment.to_sym).class
    end
  end
end

# And in the Tests...
class UserTest < Test::Unit::TestCase
  should_have_attached_file :avatar
end
```

One of Shoulda’s main goals is to remain as simple to understand and extend as
possible.  While there’s a little bit of magic when getting the current class
from the test class name, the rest of the macro is concise and easy to
understand.

We use this technique liberally throughout our test suites on a variety of
applications, and it’s worked wonders.  We even push the general purpose ones
into Shoulda proper.  If you have any that you think should be shared with the
community, just send us a Git pull request.
