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 无效的多线程。