11

I'm familiar with how the standard C++ assertion works. This has worked well in my project for a variety of testing purposes.

For example, suppose that I want to check that a certain exception is thrown by my code.

Is this possible to do without using a testing framework like CPPUnit?

user2054936
  • 131
  • 1
  • 1
  • 5
  • based on the post: http://stackoverflow.com/questions/37473/how-can-i-assert-without-using-abort . What about writing a macro that use ``catch``? – gongzhitaao Mar 27 '13 at 20:06

4 Answers4

12

You can do the same thing CPPUnit does manually:

bool exceptionThrown = false;

try
{
    // your code
}
catch(ExceptionType&) // special exception type
{
    exceptionThrown = true;
}
catch(...) // or any exception at all
{
    exceptionThrown = true;
}

assert(exceptionThrown); // or whatever else you want to do

Of course, if you use this pattern a lot, it makes sense to use a macro for this.

jplatte
  • 1,121
  • 11
  • 21
2

a skeleton (NOT TESTED)

#define MY_ASSERT(f, e) {\
    try {\
        f();\
    } catch (std::exception &e) {\
        ...\
    }\
}
gongzhitaao
  • 6,566
  • 3
  • 36
  • 44
1

Here is a exception tester that I wrote based on @JPlatte and @gongzhitaao's answers. For my test framework I have two global variables num_test and num_test_success that track how many tests are performed and how many are successful over a series of tests, but this can be changed to suit your needs.

int num_test;
int num_test_success;

#define UT_ASSERT_THROW(expression, ExceptionType) {            \
                                                                \
    try {                                                       \
        expression;                                             \
        printf("test %d:    *** FAILURE ***     %s:%d:%s,%s\n", \
               num_test, __FILE__, __LINE__,                    \
               #expression, #ExceptionType);                    \                                 
    } catch (const ExceptionType &) {                           \
        printf("test %d:    success\n", num_test);              \
        ++num_test_success;                                     \
    } catch (...) {                                             \
        printf("test %d:    *** FAILURE ***     %s:%d:%s,%s\n", \
               num_test, __FILE__, __LINE__,                    \ 
               #expression, #ExceptionType);                    \
    }                                                           \
                                                                \
    ++num_test;                                                 \
                                                                \
}

The macros __FILE__ and __LINE__ expand to the current file and line number (see https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html). The pound signs inside of the macro tell the preprocessor the place the argument as a string into the macro expansion (see http://bruceblinn.com/linuxinfo/Stringification.html).

dpritch
  • 1,149
  • 13
  • 15
-4

in-code assertions are usually used in the beginning of a method, in order to confirm that certain pre-conditions were met, before entry of this particular function for example:

Window::paint()
{
  assert(m_device != NULL);
  m_device->repaintRegion();
}

they are here primarily to catch bugs of unmet dependencies between methods or classes.

assertions in testing frameworks are differnt and usually used for unit testing, to make sure that the unit returned whatever it needed to return.

exceptions should be thrown usually where reality (i.e external systems) provided us with a case the code cannot/should not handle. its an easy way out for rare but still expected problems. for example - a time out waiting for a server usually available. or, not enough memory. I would not use it as an aid for programming logic.

to your question, there might be a way to catch exceptions in testing frameworks by surrounding the unit tested with try-catch. but i'm not sure if its really desirable.

HTH

Lior
  • 40,466
  • 12
  • 38
  • 40