yanfali ([info]yanfali) wrote,
@ 2008-05-03 19:42:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Testing Anti Pattern: Testing Exceptions
Here's the wrong way to test exceptions in C++ and Java:
bool gotExcep = false;
try {
    callSomethingThatThrows();
} catch (exception &e) {
    gotExcep = true;
}
CPPUNIT_ASSERT(gotExcept);

Here's the idiomatic way:
try {
    callSomethingThatThrows();
    CPPUNIT_FAIL("call something should have thrown an exception!");
} catch (exception &e) {
    CPPUNIT_ASSERT(true);
}

Why bother with the CPPUNIT_ASSERT(true)? Because it conveys intent. The Exception is the correct path. This idiom comes from JUnit, learn it, use it.



(Post a new comment)


[info]slothman
2008-05-04 04:11 am UTC (link)
So CPPUNIT_FAIL() throws something that doesn’t inherit from exception?

(Reply to this) (Thread)


[info]yanfali
2008-05-04 06:47 am UTC (link)
Actually it's macro magic which does this:
( CppUnit::Asserter::fail( CppUnit::Message( "forced failure", "blah" ), CppUnit::SourceLine( "../TestUnit.cpp", 30 ) ) );


Fail throws std::exception. It's usually recommended to catch something more specific than std::exception. However it works anyway because Asserter::fail's job is to log the failure. To prove that the local exception block is being executed, simply change the CPPUNIT_ASSERT(true) to false and watch it fail from there instead. The idiom itself protects you from unwanted behavior. You could easily do nothing in the exception block. However this would not communicate that the exception was the expected path. This make's it self documenting.
void testOne(void)
{
    try {
        CPPUNIT_FAIL("blah");
    } catch (exception &e) {
        CPPUNIT_ASSERT(true);
    }
}

(Reply to this) (Parent)(Thread)


[info]slothman
2008-05-04 06:52 am UTC (link)
CppUnit doesn’t get confused if the asserter has a log message but the exception thrown by CPPUNIT_FAIL() is never caught by the CppUnit infrastructure?

(Reply to this) (Parent)(Thread)


[info]yanfali
2008-05-04 07:03 am UTC (link)
Without looking deeper into the source, my guess is the message "forced failure" is used to determine wether the failure should be output during the reporting phase.

(Reply to this) (Parent)


Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…