Testing paperclip with Shoulda

Posted by Tammer Saleh

Jun 03

Josh Susser had a bunch of great things to say about Shoulda in his RailsConf 2008 presentation, 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 (which you should definitely check out if you haven’t all ready).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 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.


Comments on this post

Josh Nichols

Jun 03

Josh Nichols said,

For open source plugins/gems, how do you see people sharing these macros, ahem, class methods?

For example, I was talking with Sean Hussey the other day, and he has a should_act_as_paranoid helper he wrote.

I could see these being released as their own plugins/gems. I think gems would generally preferable, but to have proper dependencies, the shoulda rails stuff (not just the core) needs to be gemified.

Tammer Saleh

Jun 03

Tammer Saleh said,

That’s a question I’ve been asking myself, actually. I don’t really want to make everyone release separate gems/plugins with 1 or 2 shoulda macros each. I’m more inclined to create a shoulda wiki where people can share macros they’ve made.

Josh Nichols

Jun 03

Josh Nichols said,

Well, if you can gem install from a wiki and have it be versionable, I’m cool with that :)

What if you had a generator for creating a ‘shoulda plugin’ (for lack of a better term). Toss it up on github. Have a rake task for generating the gem spec. And there you go, instant gem!

Having a wiki for pointers to different macros out there certainly wouldn’t hurt though.

Eric Mill

Jun 04

Eric Mill said,

Github has a built-in Wiki, let’s use that.

Tammer Saleh

Jun 04

Tammer Saleh said,

Something like this page? :)

Sean Hussey

Jun 04

Sean Hussey said,

Thanks, Josh and Tammer. I just added the macro to the wiki. Looking for improvements if anyone has any.

Josh Nichols

Jun 04

Josh Nichols said,

Those guys at GitHub… always thinking of everything.


Sorry, comments are closed for this article.

© 2000 - 2009 by thoughtbot, inc.
written by a bushel of tiny robots