Reputation: 32645
I have the code below in my test code in many places:
//
// Make a function call while expecting an exception should be thrown
//
bool exceptionThrown = false;
try
{
expectNotEqual(someData, anotherData, methodName);
}
catch(std::logic_error&)
{
exceptionThrown = true;
}
if(!exceptionThrown)
throw std::logic_error(methodName+"exception not thrown");
It would be nice (more readable, concise) if I could encapsulate all that, and do something like:
exceptionShouldBeThrown(expectNotEqual(someData, anotherData, methodName));
I dont want to use macro ...does anyone know how I could achieve the one-liner above with C++?
Upvotes: 4
Views: 335
Reputation: 504303
I know you say no macro's, but why? They exist for generating code:
#define SHOULD_THROW(x, name) \
{ \
bool didThrow = false; \
try \
{ \
x; \
} \
catch(...) { didThrow = true; } \
\
if (!didThrow) \
throw std::logic_error(name " did not throw."); \
}
SHOULD_THROW(expectNotEqual(someData, anotherData), "expectNotEqual")
If you really don't want to use macros, you need to make a functor to call:
template <typename Func>
void should_throw(Func pFunc, const std::string& pName)
{
bool didThrow = false;
try
{
pFunc();
}
catch (...)
{
didThrow = true;
}
if (!didThrow)
throw std::logic_error(pName + " did not throw.");
}
Boost Bind helps here:
should_throw(boost::bind(expectNotEqual, someData, anotherData),
"expectNotEqual");
Of course anything that makes a functor works, like lambda's, etc. But if Boost is available, just use their testing library:
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(test)
{
BOOST_CHECK_THROW(expectNotEqual(someData, anotherData) , std::logic_error);
}
Upvotes: 11
Reputation: 3598
Exceptions are for things that are exceptional. That is, something you wouldn't expect during run time, e.g., out of memory error. You don't want to use an exception to test for common things at run time. Just have expectNotEqual return a true/false on success:
if (expectNotEqual(someData, anotherData, methodName))
{
//handle success
}
else
{
//handle failure (which would include someData==anotherData)
}
Upvotes: 2