C++ GoogleMock显示更详细的调试信息
我在工作中使用谷歌模拟。我们经常使用EXPECT\u-THROW、EXPECT\u-NO\u-THROW等 我的问题是,当一个函数被包装在一个EXPECT\u NO\u抛出中,但实际上抛出了一个异常(即代码错误)时,如何使googlemock输出异常细节和堆栈跟踪C++ GoogleMock显示更详细的调试信息,c++,googletest,googlemock,C++,Googletest,Googlemock,我在工作中使用谷歌模拟。我们经常使用EXPECT\u-THROW、EXPECT\u-NO\u-THROW等 我的问题是,当一个函数被包装在一个EXPECT\u NO\u抛出中,但实际上抛出了一个异常(即代码错误)时,如何使googlemock输出异常细节和堆栈跟踪 我得到的唯一输出是它抛出了一个异常并没有通过测试…这对于调试根本原因是没有用的。EXPECT\u-THROW,EXPECT\u-NO\u-THROW等都是Google Mock的一部分,而不是Google Mock的一部分 我不知道有
我得到的唯一输出是它抛出了一个异常并没有通过测试…这对于调试根本原因是没有用的。
EXPECT\u-THROW
,EXPECT\u-NO\u-THROW
等都是Google Mock的一部分,而不是Google Mock的一部分
我不知道有什么方法可以获得关于异常的更多信息,除了入侵gtest源代码。仅对于std::exception
s,当EXPECT\u NO\u THROW
或ASSERT\u NO\u THROW
失败时,以下更改应至少输出异常的what()
在gtest/include/gtest/internal/gtest internal.h的第1140行附近,将gtest\u TEST\u NO\u THROW\u宏更改为:
#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.")
\define GTEST\u TEST\u NO\u THROW(语句,失败)\
GTEST_含糊不清_其他_拦截器_\
如果(::测试::内部::AlwaysTrue()){\
试试{\
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_lower_(声明)\
} \
捕获(…){\
试试{\
std::exception_ptr exceptn_ptr(std::current_exception())\
std::重新提交例外情况(例外情况)\
}catch(const std::exception&exceptn){\
std::cerr我发现在单元测试二进制文件上运行gdb是最简单的。幸运的是,我们编译所有代码时启用了debug=]。您也可以一起省略断言,让您的测试用例引发异常。因此,不要断言f()
不会引发异常:
ASSERT_NO_THROW(f());
您只需调用以下函数:
f();
如果它抛出异常,它将为您提供如下输出:
C++ exception with description "something broke in f()" thrown in the test body.
<>这当然只适用于<代码> AdjtTyNojPosivs/Cuth>,因为测试用例将终止。< P>一般来说,GMOCK/GTestin不能在捕获对象上做任何事情。它不能仅仅假设代码中的子类为“代码> STD::异常< /代码>,正如您所希望的那样,C++不提供任何保存方法。引发异常时的堆栈跟踪,即使二进制文件中实际存在堆栈帧和调试符号
但是,单元测试实际上是一种验证技术,其他工具必须是您诊断的朋友。无论是添加临时日志记录(例如,printf
)或者是一个交互式调试器,比如gdb
,有更好的工具来完成这项工作。这也会影响到我在GoogleTest中的表现。我的自定义My::Exception类从std::Exception和boost::Exception中都有虚拟继承,而google test仍然无法从我覆盖的what()中获得任何有用的信息.考虑到谷歌本身,我对他们的图书馆支持率低并不感到惊讶…:-(这就是我所做的。据我所知,使用ASSERT\u no\u THROW没有任何价值,因为THROW或ASSERT都会终止测试用例,但不会终止测试套件,ASSERT宏只是掩盖了失败的原因。如果出于某种原因,您希望测试用例继续运行,即使表达式抛出了一个异常(但仍然希望测试用例失败)。我无法想象这种情况会是真的,但至少它会导致与ASSERT\u NO\u THROW不同的行为。该值有两个方面:(1)它标识了哪个测试文件/行引发了意外异常,因为在同一个测试中可能有多个位置可能引发异常,但不应该引发异常;以及(2)如果您的ASSERT\u NO\u throw()在某个函数中使用,由于其他原因,该函数本身可能位于某个具有try/catch的函数中,那么您仍然希望整个测试失败。例如,如果您创建了实现测试断言的模拟,并且它们被赋予了具有try/catch的普通/非测试对象,因为它们是为了生产而这样做的。