windows 如何在 googletest 中管理断言
How to manage assertions in googletest in windows
我正在使用 googletest 检查任何派生的 class 是否以某种方式实现了功能。
其中一个限制是,如果找不到它应该找到的数据,它应该调用 assert(false);
。如果你想知道,这是因为数据不可用是一个编程错误,它不应该发生。
现在我想为这个接口函数编写一个单元测试,我正在使用 TYPED_TEST_P
,其中要测试的 class 类型作为参数给出。
给出的例子是一个简化。
TYPED_TEST_P(InterfaceFuntionTests, CheckThatCallAssertsOnNull)
{
// All m_ prefixed variables are given from the test instantiation.
// Since we do not know what combination of values is invalid for each
// class that implements compute.
EXPECT_DEATH(m_model->compute(m_value1, m_value2, m_value3, m_value4, "Time to die.");
}
一切正常,但 Windows 想要显示 "Abort/Retry/Ignore"
window。
禁用此 Window 的最佳方法是什么?我一直认为 googletest 可能以某种方式涵盖了这一点。
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG);
// This eats the assertions and the test doesn't work.
_CrtSetReportHook(functionThatReturnsTrue);
// This eats the assertions and the test doesn't work.
请注意,此问题特定于 Windows。
我很想删除这个问题,因为我找到了一个有效的解决方案。
如果有人有更好的答案,我会把这个问题留在这里。
我的解决方案是调用 std::abort(-1);在报告挂钩函数中。
执行 std::abort(-1);
以退出给定 _CrtSetReportHook
的函数似乎使一切正常工作。
这是可行的,因为 googletest 生成了另一个进程来执行测试(使用 EXPECT_DEATH)。它实际上期待这种情况发生。
这与问题没有直接关系,但看起来这是一个 XY 问题。真正听起来像代码味道的是:
check that any derived class implements a function a certain way
如果每个派生 class 都必须抛出一个 nullptr 作为输入参数,那么您可能希望在您的接口和实际实现 class 之间有一个基础 class ]es 在调用特定的派生 class 方法之前完成一次工作。
这是 Non-Virtual 接口 (NVI) 模式的用法示例。
简而言之
headers 将是
Interface::setPtr(void * ptr) = 0 ;
BaseClass::setPtr(void * ptr) final;
BaseClass::setPtr_impl(void * ptr) = 0;
SpecificClass::setPtr_impl(void * ptr);
实施将是
BaseClass::setPtr(void * ptr) {
assert(ptr != nullptr);
setPtr_impl(ptr);
}
SpecificClass::setPtr_impl(void * ptr)
{
//actual code, ptr can not be null
}
所有这些都要求您没有可能使 ptr 无效的多线程。
我正在使用 googletest 检查任何派生的 class 是否以某种方式实现了功能。
其中一个限制是,如果找不到它应该找到的数据,它应该调用 assert(false);
。如果你想知道,这是因为数据不可用是一个编程错误,它不应该发生。
现在我想为这个接口函数编写一个单元测试,我正在使用 TYPED_TEST_P
,其中要测试的 class 类型作为参数给出。
给出的例子是一个简化。
TYPED_TEST_P(InterfaceFuntionTests, CheckThatCallAssertsOnNull)
{
// All m_ prefixed variables are given from the test instantiation.
// Since we do not know what combination of values is invalid for each
// class that implements compute.
EXPECT_DEATH(m_model->compute(m_value1, m_value2, m_value3, m_value4, "Time to die.");
}
一切正常,但 Windows 想要显示 "Abort/Retry/Ignore"
window。
禁用此 Window 的最佳方法是什么?我一直认为 googletest 可能以某种方式涵盖了这一点。
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG);
// This eats the assertions and the test doesn't work.
_CrtSetReportHook(functionThatReturnsTrue);
// This eats the assertions and the test doesn't work.
请注意,此问题特定于 Windows。
我很想删除这个问题,因为我找到了一个有效的解决方案。
如果有人有更好的答案,我会把这个问题留在这里。
我的解决方案是调用 std::abort(-1);在报告挂钩函数中。
执行 std::abort(-1);
以退出给定 _CrtSetReportHook
的函数似乎使一切正常工作。
这是可行的,因为 googletest 生成了另一个进程来执行测试(使用 EXPECT_DEATH)。它实际上期待这种情况发生。
这与问题没有直接关系,但看起来这是一个 XY 问题。真正听起来像代码味道的是:
check that any derived class implements a function a certain way
如果每个派生 class 都必须抛出一个 nullptr 作为输入参数,那么您可能希望在您的接口和实际实现 class 之间有一个基础 class ]es 在调用特定的派生 class 方法之前完成一次工作。
这是 Non-Virtual 接口 (NVI) 模式的用法示例。
简而言之 headers 将是
Interface::setPtr(void * ptr) = 0 ;
BaseClass::setPtr(void * ptr) final;
BaseClass::setPtr_impl(void * ptr) = 0;
SpecificClass::setPtr_impl(void * ptr);
实施将是
BaseClass::setPtr(void * ptr) {
assert(ptr != nullptr);
setPtr_impl(ptr);
}
SpecificClass::setPtr_impl(void * ptr)
{
//actual code, ptr can not be null
}
所有这些都要求您没有可能使 ptr 无效的多线程。