Tuesday, November 21, 2006

Ruby: Testing Rake Tasks

If you develop in Ruby and you practice Test Driven Development you may consider the question: How do I test Rake tasks?

Let's start with a task that drops each table from a database:
  desc "Wipe the database"
task :wipe => :environment do
connection = ActiveRecord::Base.connection
connection.tables.each do |table|
begin
connection.execute("drop table #{table}")
puts "* dropped table '#{table}'"
rescue
end
end
end
It may be possible to test this task in it's current form; however, rewriting the task can create a familiar and easily testable class. The key is encapsulating the behavior of the task in a class.
  desc "Wipe the database"
task :wipe => :environment do
DatabaseFacade.clean
end

class DatabaseFacade
def self.clean
connection = ActiveRecord::Base.connection
connection.tables.each do |table|
begin
connection.execute("drop table #{table}")
puts "* dropped table '#{table}'"
rescue
end
end
end
end
After moving the behavior into a class method it's possible to test the class the same as any other class.
class DatabaseFacadeTest < Test::Unit::TestCase
def test_clean_drops_all_tables
ActiveRecord::Base.expects(:connection).returns(connection=mock)
connection.expects(:tables).returns(['table1','table2'])
connection.expects(:execute).with("drop table table1")
connection.expects(:execute).with("drop table table2")
DatabaseFacade.clean
end
end
Post a Comment