MarkUs Blog

MarkUs Developers Blog About Their Project

Re-factoring contexts with Shoulda

with one comment

I’ve been playing around with Ruby on Rails for a personal project that I started in December and as we starting doing with MarkUs, I’ve been using Shoulda for my tests. One of the basic tenets of Ruby on Rails is DRY – Don’t Repeat Yourself. And I’ve often found that with Shoulda tests, I was writing the same code over and over again. I’ve had some difficulties scoping the internet for ways to re-factor Shoulda tests, but I’ve come up with two useful ways so far that I thought I would share with you. Perhaps this is just my still naivety with Ruby on Rails, but since most of us are in a similar boat, I thought I’d share my findings.

1. Class methods

This works great if your setup varies significantly between tests of a method, but you still want almost the same thing (or the exact same thing) to happen in each of the cases. You can create class methods in test class to re-factor tests like this. The key part is that you define the method prior to the highest-nested level context of any test that will use the method. I like naming them starting with should_ to clearly indicate what they’re for 🙂

def self.should_flip_active
  # Put your should statements here, including should "..." do ... end and should_*
end

2. Iterating over a set of test data

With unit tests, we shouldn’t really be using fixtures and loading everything from the database. Instead, you might just set up the few attributes that you need on a model instance to test a method on it. If you want to do this for slightly different data, then you can use either a hash or an array and make a context for each of them!

Structure with an array:

['c6conley', 'g9merika'].each do |user|
  context "with user "+user do
    # Put your setup and should statements in here - you could even make it nested further!
  end
end

Structure with a hash:

{ 'c6conley' => 5, 'g9merika' => 8 }.each do |user, section|
  context "with user "+user do
    # Do some tests on user with section
end

One last comment on Shoulda – I’ve found that you can only access assigns, e.g. assigns(:student).some_student_attribute from within should blocks. I’ve run into some problems when running my tests if I try to use assigns or a class variable like @student within an open area in a should statement. Here’s some examples:

should "work" do
  assert_equal 'hello', assigns(:student).user_name
end

# should not work
should_set_the_flash_to assigns(:student).user_name

should "work" do
  assert_contains flash.values, assigns(:student).user_name
end

Happy Shoulda testing!

Written by Tara Clark

January 26th, 2010 at 6:10 am

Posted in Uncategorized

One Response to 'Re-factoring contexts with Shoulda'

Subscribe to comments with RSS or TrackBack to 'Re-factoring contexts with Shoulda'.

  1. […] originally posted this over on the MarkUs blog.) This entry was posted in Ruby on Rails and tagged shoulda, testing. Bookmark the permalink. […]

Leave a Reply