Helpful Additions To Test::Unit
March 6th, 2007
Doing a lot of rails work, I’m getting a good feel for testing in ruby and rails. Here are some tricks / snippets I use :
assert_raises takes a string and/or a class
I want to be able to write
one = Project.new('one')
projects << one
assert_raises('project named "one" already exists') do
projects << one
end
I’ve done this a few times, but I think cruisecontrol.rb’s implementation is the most robust :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def assert_raises(arg1 = nil, arg2 = nil) expected_error = arg1.is_a?(Exception) ? arg1 : nil expected_class = arg1.is_a?(Class) ? arg1 : nil expected_message = arg1.is_a?(String) ? arg1 : arg2 begin yield fail "expected error was not raised" rescue Test::Unit::AssertionFailedError raise rescue => e raise if e.message == "expected error was not raised" assert_equal(expected_error, e) if expected_error assert_equal(expected_class, e.class, "Unexpected error type raised") if expected_class assert_equal(expected_message, e.message, "Unexpected error message") if expected_message.is_a? String assert_matched(expected_message, e.message, "Unexpected error message") if expected_message.is_a? Regexp end end |
assert_equal_sets
In Java, I used to push things into sets and compare them when I didn’t care about order. In ruby, I sometimes use assert_equal_sets. It does a compare of two arrays independent of order. So
1 2 |
assert_equal_sets [1, 3, 5], [3, 5, 1] # passes assert_equal_sets [2, 3], [3, 4] # fails |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Array def reorder_like!(other) tmp = dup clear other.each {|x| self << tmp.delete(x) if tmp.index x} tmp.each {|x| self << x } end end class Test::Unit::TestCase def assert_equal_sets(expected, actual) actual.reorder_like!(expected) assert_equal(expected, actual) end end |
file_sandbox for testing against the file system
After dragging this code around me for the last 6 or 7 projects I’ve been on, I finally packaged it up as a gem . It lets you write code like :
1 2 3 4 5 |
in_sandbox do |sandbox| sandbox.new :file => 'b/a.txt', :with_contents => 'some stuff' assert_equal 'some_stuff', File.read(sandbox.root + '/b/a.txt') end |
Basically it creates a temporary directory for you to muck about in. After the block is ended (or teardown is called on your test) that directory and everything in it is guaranteed to be cleaned up. It also has a bunch of methods to make file based things easier like creating a file, etc.
Install it with “gem install file_sandbox”

Sorry, comments are closed for this article.