- Thoughts on the overall idea of assertions returning values,
particularly pitfalls you see with it.
No thoughts here, though I find having assert_raises return
the exception raised useful for further testing on the
exception object (below). Similar arguments for
assert_match, though I had not thought to do that until now.
First of all, thanks for replying, Matt! I’m sorry it has taken so long
for me to get back to this.
In response to your statement about finding the exception return value
useful, I guess the question is, is it more readable (and not too
difficult) to do one of the following instead:
begin
raise “exception message”
flunk(“Should have thrown an exception”)
rescue Exception => e
assert_equal(“exception message”, e.message, “Expected a message”)
end
or,
assert_raises_with_message(Exception, “exception message”, “Expected
exception”) do
raise “exception message”
end
I realize the name in the latter example is perhaps not the best, but
it’s the idea of using a more specific assertion for the case of wanting
to check the message. Of course, there are other potentially interesting
bits of an exception, which is what I personally don’t like about it
(and I don’t like the verbosity of the first way).
- Code examples using the current return values from #assert_match
and #assert_raises.
This is using RUnit’s assert_exception, but you get the idea.
I use it all the time to make sure the expected exception is
the one I think it is by examining the message.
defer_reason = "I might not like you any more"
lda, log = new_lda
e = assert_exception(RFilter::DeliveryAgent::DeliveryDefer) {
lda.defer(defer_reason)
}
assert_equal(e.message, defer_reason)
Let me rewrite this with my two alternatives above:
defer_reason = “I might not like you any more”
lda, log = new_lda
begin
lda.defer(defer_reason)
flunk
rescue RFilter::DeliveryAgent::DeliveryDefer => e
assert_equal(e.message, defer_reason)
end
or
defer_reason = “I might not like you any more”
lda, log = new_lda
assert_exception(RFilter::DeliveryAgent::DeliveryDefer, defer_reason)
{
lda.defer(defer_reason)
}
Hmmm… after seeing that, I’m leaning towards leaving the return value
to #assert_raises. The first way is just too much work, and the second
way doesn’t give me enough power. It just seems more robust to allow the
ability to inspect anything in the exception, instead of being
constrained by what the framework designer thought you should be able to
check.
- Code examples showing the use of return values from other
assertions.
I don’t know if Test::Unit has the equivalent of RUnit’s
assert_no_exception, but I have used it this way:
h = RMail::Header.new
# This time is out of the range that can be represented by a
# Time object.
h.add_raw("Date: Sun, 14 Jun 2065 05:51:55 +0200")
t = assert_no_exception {
h.date
}
assert_nil(t)
I don’t really understand what you’re testing here…
#assert_no_exception (or, in Test::Unit’s case, #assert_nothing_raised)
will fail already if an exception is thrown, so why the extra check
afterwards? From looking at RubyUnit’s source, there doesn’t even seem
to be an explicit return value from this method.
What I’m thinking at the moment is:
- Leave in the return value from #assert_raises.
- Remove the return value from #assert_match.
- In general, avoid returning (documented) values from assertions.
To clarify #3, I don’t plan on returning nil from all the assertions,
but I do plan on not explicitly returning something useful from them,
and saying that if you depend on something that is returned as a side
effect, too bad for you if it changes.
Thoughts?
Nathaniel
<:((><
···
Matt Armstrong [mailto:matt@lickey.com] wrote:
RoleModel Software, Inc.
EQUIP VI