2015-10-14 3 views
6

У меня есть два модульных теста, которые разделяют какое-то состояние (к сожалению, я не могу это изменить, так как нужно проверить обработку этого самого состояния).Как я могу сообщить 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): error: Mock function called more times than expected - returning directly. 
    Function call: Foo(0068F65C) 
     Expected: to be called once 
      Actual: called twice - over-saturated and active 

ожидание, которое не является один в test1. Вызов имеет место, но я хотел бы сказать GoogleMock не заботясь после завершения test1 (на самом деле, я хочу только проверить ожидания в тесте во время теста).

Я был под впечатлением, что RetiresOnSaturation бы это сделать, но с ним я получаю:

 
Unexpected mock function call - returning directly. 
    Function call: Foo(005AF65C) 
Google Mock tried the following 1 expectation, but it didn't match: 

mytest.cpp(42): EXPECT_CALL(first, Foo(_))... 
     Expected: the expectation is active 
      Actual: it is retired 
     Expected: to be called once 
      Actual: called once - saturated and retired 

Что я должен признать, что меня смущает. Что это значит? Как я могу это решить?

+0

'SubscribeToFooCallsGlobal (first);' - вы, вероятно, должны отказаться от подписки в конце каждого TC. – PiotrNycz

+0

@PiotrNycz Конечно, но это обходное решение.Почему GoogleMock все еще проверяет вызов * после завершения теста? –

+0

Поскольку глобальные переменные являются глобальными. И как таковые (эти глобальные перемены) являются болью в a * s, и никто и ничто (в том числе и gtest) не может правильно справиться с глобальными значениями – PiotrNycz

ответ

5

Вы можете прочитать в documentation of Mock почти буквально описал свой случай:

Принудительная проверка

Когда это время destoyed, ваш дружественный фиктивный объект будет автоматически проверить, что все ожидания на нем были удовлетворены, и будет генерировать ошибки Google Test, если нет. Это удобно, поскольку он оставляет вам с одной минутой, о чем можно беспокоиться. То есть, если вы не уверены, что ваш макет будет уничтожен.

Как может быть, что ваш макет не будет уничтожен? Ну, это может быть создано на куче и принадлежит вам код . Предположим, что в этом коде есть ошибка, и он не удаляет объект-макет должным образом - вы можете пройти тест прохождения, когда на самом деле есть ошибка.

Поэтому вы не должны ожидать, что в конце тестового примера каким-то магическим способом ожидания будут «деактивированы». Как упоминалось выше, макет деструктора является точкой проверки.

В вашем случае - вы издевательства не являются локальными переменными - они создаются в динамической памяти (куча в цитированном документе) и хранятся в вашем тестируемом коде через SubscribeToFooCallsGlobal(), поэтому наверняка макет, созданный в одном тесте, все еще жив в следующем тесте ,

Простое и правильное решение - отказаться от подписки в конце каждого TC - я не знаю, есть ли у вас UnsubscribeToFooCallsGlobal() - если нет - создайте такую ​​функцию. Чтобы быть уверенным, что это всегда будет вызвано - используйте ScopeGuard pattern.

Существует одна функция для принудительной проверки вручную Mock::VerifyAndClearExpectations(&mock_object) - но используйте ее, только если вам нужна эта проверка не в последней строке вашего тестового теста, потому что это должно быть точкой разрушения.