MetaSkills.net

Coulda Shoulda Woulda

Posted On: May 29th, 2008 by kencollins

It has been about 6 months now since I started using the Shoulda testing plugin as my BDD/TDD tool of choice. Unlike a lot of other people, I did not flock to the RSpec bandwaggon. Personally I think RSpec is horribly bloated a sledgehammer for a simple issue, the need to have test code organized with nested setups and context blocks.

If you are new to Shoulda, I highly urge you to take a look at the Thoughbot project page for it. If you have the time take a look at some of their other projects, like Paperclip. These guys are really smart. If you really want to see how shoulda can sing, check out Tammer Saleh's presentation of it at the MountainWest RubyConf 2008. In that presentation he covers how you can extend Shoulda and write your own macros that generate additional tests. This is what my blog post is about.

Sample Shoulda Macro For Functional Require Login

Here is a simple module that you might find for any restful authentication system. This would be included in your main test_helper.rb file where it would add the normal login_as(user) method. The good part I want to point out is the should_require_login(*actions) macro method that shows off a neat example of how you could use Shoulda in your functional tests at the class level.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

module AuthSystem
  module TestHelper
    
    def self.included(receiver)
      receiver.extend ClassMethods
      receiver.send :include, InstanceMethods
    end
    
    module ClassMethods
      
      def should_require_login(*actions)
        actions.each do |action|
          should "Require login for '#{action}' action" do
            get(action)
            assert_redirected_to(login_url)
          end
        end
      end
      
    end
    
    module InstanceMethods
      
      def login_as(user)
        if u = users(user)
          @request.session[:user_id] = u.id
        end
      end
      
    end
    
  end
end

Here is how it would look in the controller functional test. These are all contrived examples, but I think it illustrates how Shoulda can be used and in general how you can make your own macros that test at a higher level.

1
2
3
4
5
6

class UsersControllerTest < ActionController::TestCase
  
  should_require_login :edit, :update, :etc
  
end

Ken Collins

  HOMEPAGE  | June 7th, 2008 at 02:25 PM
Ken Collins

Adding my own addition here. I have found that the "should_require_login" method should have a logout at the top of the method. So like this.

    def should_require_login(*actions)
      actions.each do |action|
        should "Require login for '#{action}' action" do
          logout
          get(action)
          assert_redirected_to(login_url)
        end
      end
    end

My logout method looks like this:

    def logout
      @request.reset_session
    end

Don

  HOMEPAGE  | June 14th, 2008 at 12:42 AM
Don I'm trying to find your Omnigraffle template for Ruby Databases... can you point me to a download link?

Ken Collins

  HOMEPAGE  | June 14th, 2008 at 02:11 PM
Ken Collins Sadly I could not find that from any of my backups. It somehow got lost in the move from Drupal to Mephisto. Sorry!

Leave a Comment

Name (required)
Email (will not be published)
Website
Comment