Как управлять утверждениями в googletest в windows - PullRequest
0 голосов
/ 21 сентября 2018

Я использую googletest, чтобы проверить, что любой производный класс реализует функцию определенным образом.

Одним из ограничений является то, что он должен вызывать assert(false);, если он не может найти данные, которые должен найти,Если вы хотите знать, это потому, что недоступные данные являются ошибкой программирования, и это никогда не должно произойти.

Теперь я хочу написать модульный тест для этой функции интерфейса, я использую TYPED_TEST_Pгде тип класса для тестирования задан в качестве параметра.

ДАННЫЙ ПРИМЕР ПРОСТОЙ.

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".

Как лучше всего отключить это окно?Я продолжаю думать, что 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);в функции ловушки отчета.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Это напрямую не связано с вопросом, но похоже, что это проблема XY.Что действительно звучит как запах кода:

проверить, что любой производный класс реализует функцию определенным образом

Если каждый производный класс должен бросить, если ему даноnullptr в качестве входного параметра, тогда вы можете захотеть иметь базовый класс между вашим интерфейсом и фактическими классами реализации, который выполняет работу один раз перед вызовом определенных методов производного класса.

Это пример использования NonШаблон виртуального интерфейса (NVI).

В двух словах заголовки будут

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.

0 голосов
/ 21 сентября 2018

Выполнение std::abort(-1); для выхода из функции, данной _CrtSetReportHook, похоже, заставляет все работать правильно.

Это работает, потому что googletest запускает другой процесс для выполнения теста (с EXPECT_DEATH).И это на самом деле ожидает, что это произойдет.

...