Test::Unit assert_raise_s

E

Edwin Fine

Some time ago, I complained about assert_raise requiring one to list
specific exceptions in a test case. My issue is that I wanted to test
for the raising of a base exception OR any exception derived from that
base exception, because I did not want to have to change the unit tests
every time a different exception subclass is thrown by the method under
test or anything it calls.

I dynamically added a new assert function to Test::Unit, named
assert_raise_s, which works this way. It should not break any existing
Test::Unit functionality. At least one person emailed me and asked me to
provide the code for this function, so I am posting it here in case
others might want it, too. I think that Daniel Berger also talked about
needing something like this some time ago (he wasn't the person who
emailed me).

In your test case file(s), you just need to

require 'test/unit'
require 'assert_raise_s'
----
assert_raise_s.rb:

module Test
module Unit
module Assertions

private

def _expected_exception_or_subclass?(actual_exception, exceptions,
modules) # :nodoc:
exceptions.any? {|cls| actual_exception.class <= cls } or
modules.any? {|mod| actual_exception.is_a?(mod)}
end

##
# Passes if the block raises one of the given exceptions or its
descendants.
#
# Example:
# assert_raise_s RuntimeError, LoadError do
# raise 'Boom!!!'
# end

public

def assert_raise_s(*args)
_wrap_assertion do
if Module === args.last
message = ""
else
message = args.pop
end
exceptions, modules = _check_exception_class(args)
expected = args.size == 1 ? args.first : args
actual_exception = nil
full_message = build_message(message, "<?> exception expected
but none was thrown.", expected)
assert_block(full_message) do
begin
yield
rescue Exception => actual_exception
break
end
false
end
full_message = build_message(message, "<?> exception expected
but was\n?", expected, actual_exception)
assert_block(full_message)
{_expected_exception_or_subclass?(actual_exception, exceptions,
modules)}
actual_exception
end
end
end
end
end
 
D

Daniel Berger

Some time ago, I complained about assert_raise requiring one to list
specific exceptions in a test case. My issue is that I wanted to test
for the raising of a base exception OR any exception derived from that
base exception, because I did not want to have to change the unit tests
every time a different exception subclass is thrown by the method under
test or anything it calls.

I dynamically added a new assert function to Test::Unit, named
assert_raise_s, which works this way. It should not break any existing
Test::Unit functionality. At least one person emailed me and asked me to
provide the code for this function, so I am posting it here in case
others might want it, too. I think that Daniel Berger also talked about
needing something like this some time ago (he wasn't the person who
emailed me).

Yep, In my case I would like this functionality for validating system
errors (i.e. Errno::) where you don't know in advance exactly what
type of Errno a given method is going to raise because they can be
platform specific.
In your test case file(s), you just need to

<snip>

Nice. Can you please re-tool this as a patch to test-unit and submit
it to ruby-core?

Thanks,

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top