I want to test the gcd function using assertions, but I don't know how to catch the exception(and prevent the program from crashing).
int gcd(int a, int b) {
if(a<0 || b<0) {
throw "Illegal argument";
}
if(a==0 || b==0)
return a+b;
while(a!=b) {
if(a>b) {
a = a - b;
}
else {
b = b - a;
}
}
return a;
}
void test_gcd() {
assert(gcd(16,24) == 8);
assert(gcd(0, 19) == 19);
try {
gcd(5, -15);
assert(false);
} catch (char* s) {
assert(true);
cout << "Illegal";
}
}
"I want to test the gcd function using assertions, but I don't know how to catch the exception (and prevent the program from crashing)."
As stated in the reference documentation assert()
is an implementation defined macro (emphasis mine):
#ifdef NDEBUG #define assert(condition) ((void)0) #else #define assert(condition) /*implementation defined*/ #endif
If
NDEBUG
is not defined, thenassert
checks if its argument (which must have scalar type) compares equal to zero. If it does, assert outputs implementation-specific diagnostic information on the standard error output and callsstd::abort
. The diagnostic information is required to include the text of expression, as well as the values of the standard macros__FILE__
,__LINE__
, and the standard variable__func__
.
Thus assert()
doesn't throw an exception you can catch. To test your code and correct usage of exceptions you should have something like the following, where expect_true()
is something that prints a message, if the parameter evaluates to false
and doesn't abort()
your program:
int gcd(int a, int b) {
if(a<0 || b<0) {
throw std::invalid_argument("a and b must be negative values");
}
// ...
}
#define expect_true(arg) \
do { \
if(!(arg)) { \
std::cout << "Unexpected false at " \
<< __FILE__ << ", " << __LINE__ << ", " << __func__ << ": " \
<< #arg \
<< std::endl; } \
} while(false);
void test_gcd() {
expect_true(gcd(16,24) == 8);
expect_true(gcd(0, 19) == 19);
bool exceptionCaught = false;
try {
gcd(5, -15);
} catch (const std::invalid_argument& ex) {
cout << "Illegal as expected" << endl;
exceptionCaught = true;
}
expect_true(exceptionCaught);
}
Here's a fully working version. And another sample failing the test case.
Also since assert()
will always abort your test_gcd()
function, that's a bit tedious way to do unit testing. I'd recommend using a decent unit testing framework, where you have more control over testing expectations and running various test cases. E.g. use something like Google Test (which will have an implementation for EXPECT_TRUE()
).