Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoogleMock display more detailed debug info

I'm using googlemock at work. We often use EXPECT_THROW, EXPECT_NO_THROW etc...

My question is how do you make googlemock output the exception details and maybe a stack trace when a function is wrapped in a EXPECT_NO_THROW, but actually throws an exception(ie code bug)?

The only output I get is that it threw an exception and failed the test...which is not useful for debugging the root cause.

like image 381
user623879 Avatar asked Jul 11 '12 18:07

user623879


2 Answers

EXPECT_THROW, EXPECT_NO_THROW, etc. are really part of Google Test rather than Google Mock.

I don't know of any way to get further info on the exception other than hacking the gtest source. For std::exceptions only, the following change should at least output the exception's what() when an EXPECT_NO_THROW or ASSERT_NO_THROW fails.

In gtest/include/gtest/internal/gtest-internal.h, around line 1140, change the GTEST_TEST_NO_THROW_ macro to:

#define GTEST_TEST_NO_THROW_(statement, fail) \
  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  if (::testing::internal::AlwaysTrue()) { \
    try { \
      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
    } \
    catch (...) { \
      try { \
        std::exception_ptr exceptn_ptr(std::current_exception()); \
        std::rethrow_exception(exceptn_ptr); \
      } catch(const std::exception& exceptn) { \
        std::cerr << exceptn.what() << '\n'; \
      } \
      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
    } \
  } else \
    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
      fail("Expected: " #statement " doesn't throw an exception.\n" \
           "  Actual: it throws.")

You can obviously add more functionality here; catching custom exception types, formatting the failure message to include the exception info, etc.

like image 181
Fraser Avatar answered Oct 10 '22 18:10

Fraser


You can also omit the assertion alltogether and let your test case throw an exception. So instead of asserting that f() does not throw:

ASSERT_NO_THROW(f());

you simply call the function:

f();

If it throws an exception, it will give you an output like this one:

C++ exception with description "something broke in f()" thrown in the test body.

This of course only works with ASSERT_NO_THROW, because the test case will terminate.

like image 45
morxa Avatar answered Oct 10 '22 17:10

morxa