2015-10-14 13 views
6

Mam dwa testy jednostkowe, które mają pewien stan (niestety nie mogę tego zmienić, ponieważ chodzi o przetestowanie obsługi tego stanu).Jak mogę nakazać GoogleMockowi przerwanie sprawdzania oczekiwań po zakończeniu testu?

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 
} 

Jeśli przeprowadzę testy osobno, oba są skuteczne. Jeśli uruchomić je w kolejności, test1 test2 będę się następujący błąd w 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 

oczekiwaniem, że nie jest jedynym w test1. Połączenie ma miejsce, ale chciałbym powiedzieć GoogleMock nie dbał o po zakończeniu test1 (w rzeczywistości, chcę sprawdzić oczekiwania w teście podczas testu).

Byłem pod wrażeniem, że RetiresOnSaturation byłoby to zrobić, ale z niej uzyskać:

 
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 

Które muszę przyznać, że myli mnie. Co to znaczy? Jak mogę to rozwiązać?

+0

'SubskrybujToFooCallsGlobal (pierwszy);' - prawdopodobnie musisz zrezygnować z subskrypcji na końcu każdego TC. – PiotrNycz

+0

@PiotrNycz Pewnie, ale to obejście.Dlaczego GoogleMock nadal sprawdza połączenie * po uruchomieniu testu? –

+0

Ponieważ globale są globalne. I jako takie (te globale) są bóle a * s - i nikt i nic (łącznie z gtest) nie radzi sobie właściwie z globaliami – PiotrNycz

Odpowiedz

5

można przeczytać w documentation of Mock niemal dosłownie opisane sprawy:

Wymuszenie weryfikacji

Kiedy to jest destoyed, twój przyjazny atrapa obiektu automatycznie sprawdzić, czy wszystkie oczekiwania na nim zostały spełnione, i będzie generować niepowodzenia testów Google, jeśli nie. Jest to wygodne, ponieważ pozostawia jedną mniejszą rzecz, o którą trzeba się martwić. To znaczy, jeśli nie jesteś pewien, że twój fałszywy obiekt zostanie zniszczony.

Jak to możliwe, że twój fałszywy obiekt nie zostanie ostatecznie zniszczony? No cóż, może on zostać utworzony na stercie i należy do niego testowanie. Załóżmy, że w tym kodzie występuje błąd i nie usuwa on prawidłowo obiektu próbnego - może się zdarzyć, że podczas testu pojawi się błąd.

Nie należy się więc spodziewać, że pod koniec testu, w jakiś magiczny sposób, oczekiwania zostaną "dezaktywowane". Jak wspomniano powyżej - punktem kontrolnym jest pozorny destruktor.

W twoim przypadku - wyśmiewanie się nie jest zmienną lokalną - są one tworzone w pamięci dynamicznej (stertę w cytowanym dokumencie) i przechowywane w testowanym kodzie przez SubscribeToFooCallsGlobal(), więc z całą pewnością sztucznie stworzony w jednym teście wciąż żyje w następnym teście .

Prostym i właściwym rozwiązaniem jest wypisanie się pod koniec każdego TC - nie wiem, czy masz jakieś UnsubscribeToFooCallsGlobal() - jeśli nie - utwórz taką funkcję. Aby mieć pewność, że będzie on zawsze wywoływany, użyj ScopeGuard pattern.

Istnieje jedna funkcja ręcznego wymuszania weryfikacji Mock::VerifyAndClearExpectations(&mock_object) - ale użyj jej tylko wtedy, gdy ta weryfikacja nie jest wymagana w ostatniej linii testówki, ponieważ powinno to być punktem zniszczenia.

Powiązane problemy