Rails special sauce: Test::Unit setup and teardown

Rails adds plenty of special sauce to Ruby standard library.

Being a fan of testing and all that, let me show you what I found while spelunking around the Rails supporting test cases:

The revelation

module ActionMailer class TestCase < ActiveSupport :: TestCase setup :initialize_test_deliveries protected def initialize_test_deliveries # ... snip ... end # ... snip ... end end

The shock

What the?!?! I thought you had to def setup for setup methods…. but here, it’s a method call, that takes a symbol.

The realization

This reminds me of something…

class Subscription < ActiveRecord :: Base before_create :record_signup private def record_signup self . signed_up_on = Date . today end end

Shocking to say, but they are similar, because they both use ActiveSupport::Callbacks. Basically, this allows us to specify setup and teardown blocks the same way we’ve been specifying ActionController filters and ActiveRecord callbacks:

Using a method name as a symbol

Using a block

Using a method

Using conditions

Determined by a lambda

Determined by a method name as a symbol

The experiment

Let’s try using these all together:

require 'rubygems' require 'active_support' require 'active_support/test_case' require 'test/unit' class ExampleTest < Test :: Unit :: TestCase def setup puts "called from def setup" end setup :setup_with_symbol setup :setup_never_called , :if => :never setup :setup_never_called , :if => lambda { false } setup do puts "called from a block" end def setup_with_symbol puts "called by using symbol of a method name" end def test_nothing puts "I am testing nothing" assert true end def setup_never_called flunk "Should never be displayed" end def never false end end

This outputs:

Loaded suite test-test Started called by using symbol of a method name called from a setup block called from def setup I am testing nothing . Finished in 0.000371 seconds. 1 tests, 1 assertions, 0 failures, 0 errors

The conclusion

So why is this significant?