Как я могу сказать GoogleMock прекратить проверку ожидания после завершения теста?
У меня есть два модульных теста, которые разделяют какое-то состояние (к сожалению, я не могу изменить это, поскольку цель состоит в том, чтобы проверить обработку этого самого состояния).
TEST(MySuite, test1)
{
shared_ptr<MockObject> first(make_shared<MockObject>());
SubscribeToFooCallsGlobal(first);
EXPECT_CALL(*first, Foo(_));//.RetiresOnSaturation();
TriggerFooCalls(); // will call Foo in all subscribed
}
TEST(MySuite, test2)
{
shared_ptr<MockObject> second(make_shared<MockObject>());
SubscribeToFooCallsGlobal(second);
EXPECT_CALL(*second, Foo(_)).Times(1);
TriggerFooCalls(); // will call Foo in all subscribed
}
Если я запускаю тесты отдельно, оба успешны. Если я буду запускать их в порядке test1, test2, я получу следующую ошибку в test2:
mytest.cpp (42): ошибка: фиктивная функция вызывается чаще, чем ожидалось, и возвращает результат напрямую. Вызов функции: Foo(0068F65C) Ожидаемый: будет вызван один раз Актуально: вызывается дважды - перенасыщен и активен
Ожидание, которое терпит неудачу, является тем в test1. Вызов происходит, но я бы хотел сказать GoogleMock, что после test1
завершено (на самом деле, я хочу проверять ожидания только во время теста).
У меня сложилось впечатление, что RetiresOnSaturation
сделал бы это, но с этим я получаю:
Неожиданный вызов фиктивной функции - возврат напрямую. Вызов функции: Foo(005AF65C) Google Mock попробовал следующее 1 ожидание, но оно не совпало: mytest.cpp(42): EXPECT_CALL(сначала Foo(_))... Ожидаемый: ожидание активно Фактически: он на пенсии Ожидаемый: будет вызван один раз Актуальные: называются один раз - насыщенные и на пенсии
Что я должен признать, смущает меня. Что это значит? Как я могу решить это?
1 ответ
Вы можете прочитать в документации Mock почти буквально описанный ваш случай:
Принудительное подтверждение
Когда его убирают, ваш дружественный фиктивный объект автоматически проверит, что все ожидания на нем были удовлетворены, и, если нет, сгенерирует ошибки Google Test. Это удобно, так как вам остается меньше беспокоиться. То есть, если вы не уверены, что ваш ложный объект будет разрушен.
Как могло случиться, что ваш фиктивный объект в конечном итоге не будет уничтожен? Ну, он может быть создан в куче и принадлежать коду, который вы тестируете. Предположим, что в этом коде есть ошибка, и она не удаляет фиктивный объект должным образом - вы можете в конечном итоге пройти тест, когда на самом деле есть ошибка.
Так что вы не должны ожидать, что в конце теста, каким-то волшебным образом, ожидания будут "деактивированы". Как указано выше, фиктивный деструктор является точкой проверки.
В вашем случае - вы mocks не локальные переменные - они создаются в динамической памяти (куча в цитируемом документе) и хранятся в тестируемом коде через SubscribeToFooCallsGlobal()
, Так что наверняка макет, созданный в одном тесте, все еще жив в следующем тесте.
Простое и правильное решение - отписаться в конце каждого TC - я не знаю, есть ли у вас UnsubscribeToFooCallsGlobal()
- если нет - создайте такую функцию. Чтобы быть уверенным, что он будет вызываться всегда - используйте шаблон ScopeGuard.
Существует одна функция для принудительной проверки Mock::VerifyAndClearExpectations(&mock_object)
- но используйте его, только если вам нужна эта проверка не в последней строке вашего тестового примера, потому что это должно быть точкой разрушения.