I am a little bit late to the party, but here's one approach which works:
/**
* @brief Wrap a code block with try-catch, handle exceptions thrown, print them
* into EXCEPT_STREAM and rethrow.
*/
#define PRINT_AND_RETHROW(CODE_BLOCK, EXCEPT_STREAM) try{do{ CODE_BLOCK }while(0);}catch(const std::exception& ex){ EXCEPT_STREAM << "std::exception thrown: " << ex.what() << std::endl; throw; }catch(...){ EXCEPT_STREAM << "unknown structure thrown" << std::endl; throw;}
/**
* @brief Wrap a code block with try-catch, handle exceptions thrown, print them
* into std::cerr and rethrow.
*/
#define PRINT_STDERR_AND_RETHROW(CODE_BLOCK) PRINT_AND_RETHROW(CODE_BLOCK, std::cerr)
#define EXPECT_NO_THROW_PRINT(CODE_BLOCK) EXPECT_NO_THROW(SPECTRE_PRINT_STDERR_AND_RETHROW(CODE_BLOCK))
#define ASSERT_NO_THROW_PRINT(CODE_BLOCK) ASSERT_NO_THROW(SPECTRE_PRINT_STDERR_AND_RETHROW(CODE_BLOCK))
Later in code, replace *_NO_THROW
's with *_NO_THROW_PRINT
and voila.
void f(){
throw std::runtime_error{"this should be printed"};
}
TEST(test, test){
EXPECT_NO_THROW_PRINT( f(); );
}
Expected output of test case above:
Running main() from /build/googletest-qXr8Ln/googletest-1.10.0/googletest/src/gtest_main.cc
Note: Randomizing tests' orders with a seed of 60645 .
[==========] Running 2 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 1 test from test
[ RUN ] test.test
std::exception thrown: this should be printed
/workspace/libasync/test/ut_executor_factory.cpp:56: Failure
Expected: try{do{ f(); }while(0);}catch(const std::exception& ex){ std::cerr << "std::exception thrown: " << ex.what() << std::endl; throw; }catch(...){ std::cerr << "unknown structure thrown" << std::endl; throw;} doesn't throw an exception.
Actual: it throws.
[ FAILED ] test.test (0 ms)
[----------] 1 test from test (0 ms total)
EXPECT_NO_THROW
at all. If/when it throws, then you'll see the exception message as the gtest harness will display it. However, this only works for the first exception, because the test ends right away. – Kalvn