2015-10-26 12 views
8

W Mockito możemy określić wiele zwrotów takich jak (zaczerpnięte z here):Jak określić kolejne zwroty w gmock?

//you can set different behavior for consecutive method calls. 
//Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls. 
when(mock.someMethod("some arg")) 
    .thenReturn(new RuntimeException()) 
    .thenReturn("foo"); 

//There is a shorter way of consecutive stubbing: 
when(mock.someMethod()).thenReturn(1,2,3); 
when(mock.otherMethod()).thenThrow(exc1, exc2); 

Czy istnieje sposób, aby określić wiele powroty dla mock wykonana z gmock? Obecnie mam:

store_mock_ = std::make_shared<StorageMock>(); 
ON_CALL(*store_mock_, getFileName(_)).Return("file1").Return("file2"); 

które nie skompilować, ponieważ nie mogę dowiedzieć się kilku zwrotów w gmock. Czy to możliwe w przypadku gmock? Jeśli nie, czy istnieje inny sposób rozwiązania tego problemu? Odkryłam, że możemy EXPECT wiele wartości powrotne lubię:

using ::testing::Return;... 
EXPECT_CALL(turtle, GetX()) 
    .WillOnce(Return(100)) 
    .WillOnce(Return(200)) 
    .WillOnce(Return(300)); 

Jednak nie znaleziono żadnych docs dla wyśmianie wiele zwrotów z ON_CALL.

Odpowiedz

9

ON_CALL służy bardziej do ustawienia domyślnego zachowania funkcji. To znaczy. wiesz, że w testowanym kodzie wywoływana jest wyśmiewana funkcja, chcesz ustawić pewną domyślną wartość, ale nie jest tak naprawdę ważne, ile razy funkcja jest wywoływana.

example:

ON_CALL(foo, Sign(_)) 
     .WillByDefault(Return(-1)); 
    ON_CALL(foo, Sign(0)) 
     .WillByDefault(Return(0)); 
    ON_CALL(foo, Sign(Gt(0))) 
     .WillByDefault(Return(1)); 

Aby uzyskać pożądane zachowanie użyję expectations - już pod warunkiem jakiś przykład w pytaniu, żeby pokazać więcej - przykład kiedy można oczekiwać 1, 2 wtedy zawsze 3:

EXPECT_CALL(foo, Sign(_)) 
     .WillOnce(Return(1)) 
     .WillOnce(Return(2)) 
     .WillRepeatedly(Return(3)); 

EXPECT_CALL „sposób” może być kłopotliwe, gdy chcesz ustawić to w urządzeniu testowym SetUp - a niektóre testy m ight call foo tylko jeden raz. Ale, oczywiście, istnieją sposoby, aby „kontrola” wartość ON_CALL powrót do kolejnych rozmów - ale trzeba to zrobić za pomocą specjalnych działań - jak się wynikiem jakiejś funkcji - jak w poniższym przykładzie:

class IDummy 
{ 
public: 
    virtual int foo() = 0; 
}; 

class DummyMock : public IDummy 
{ 
public: 
    MOCK_METHOD0(foo, int()); 
}; 
using namespace ::testing; 
class DummyTestSuite : public Test 
{ 
protected: 
    DummyMock dummy; 
    void SetUp() override 
    { 
     ON_CALL(dummy, foo()) 
      .WillByDefault(
       InvokeWithoutArgs(this, &DummyTestSuite::IncrementDummy)); 
    } 
    int dummyValue = 0; 
    int IncrementDummy() 
    { 
     return ++dummyValue; 
    } 

}; 


TEST_F(DummyTestSuite, aaa) 
{ 
    ASSERT_EQ(1, dummy.foo()); 
    ASSERT_EQ(2, dummy.foo()); 
    ASSERT_EQ(3, dummy.foo()); 

} 
+1

Moje zrozumienie oczekiwań jest tym, czego oczekujemy, że zostaną zwróceni, a nie tym, co faktycznie powinno zostać zwrócone przez próbę. Czy to jest nieprawidłowe? Twój przykład "IncrementDummy" jest naprawdę pomocny. Kinda ssie, że najlepszy sposób definiowania wielu zwrotów jest tak zaangażowany. :( –

+2

Jeśli rozumiem cię poprawnie - to tak, mój przykład jest bardzo sztuczny - nigdy nie testujemy twierdzeniem, co mity powraca - po prostu piszę ten test, aby pokazać, że ten mechanizm działa. Bardziej ogólne możemy powiedzieć, że 'EXPECT_CALL'jest dla przypadki, w których oczekuje się, że wyszydzona funkcja zostanie wywołana z poziomu testowanego kodu, nie jest konieczne ustawienie "wartości zwracanej" - np. często jest tak, że oczekujemy wywołania funkcji pustej. – PiotrNycz