2015-10-26 29 views
8

In Mockito possiamo specificare più ritorni come (tratto da here):Come specificare i ritorni consecutivi in ​​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); 

C'è un modo per specificare più ritorni per un finto realizzato con gmock? Attualmente ho:

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

che non viene compilato perché non riesco a capire più restituzioni in gmock. È possibile con gmock? In caso contrario, c'è un altro modo per risolvere questo problema? Ho scoperto che siamo in grado di EXPECT più valori di ritorno come:

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

Tuttavia, non ho trovato alcuna documentazione per il beffardo multipli ritorna con ON_CALL.

risposta

9

ON_CALL è più utilizzato per impostare il comportamento predefinito della funzione. Cioè sai che nel codice testato viene chiamata la funzione derisoria, si desidera impostare un valore predefinito, ma non è realmente importante quante volte viene chiamata la funzione.

Il 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)); 

per ottenere il vostro comportamento desiderato userei expectations - già fornito alcuni esempi in questione, solo per mostrare di più - un esempio quando ci si aspetta 1, 2 poi sempre 3:

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

EXPECT_CALL "via" potrebbe essere fastidioso quando si desidera impostare questo nel dispositivo di prova SetUp - e alcuni test m ight chiamare foo una sola volta. Ma, naturalmente, ci sono modi per valore ON_CALL di ritorno "controllo" per le chiamate successive - ma è necessario farlo con azioni speciali - come ottenere risultato di una qualche funzione - come in questo esempio:

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

mia comprensione delle aspettative è che sono ciò che ci aspettiamo di essere restituiti, non ciò che dovrebbe essere effettivamente restituito dalla simulazione. È sbagliato? Il tuo esempio di 'IncrementDummy' è davvero utile. Mi piace che il modo migliore per definire i ritorni multipli sia così coinvolto. :( –

+2

Se ti capisco bene - allora sì. Il mio esempio è molto artificiale - non testiamo mai per asserzione cosa restituisce i mock - scrivo questo test per dimostrare che questo meccanismo funziona. Più in generale possiamo dire che EXPECT_CALL'è per casi in cui ci aspettiamo che venga chiamata la funzione fittizia dal codice testato. Non è necessario impostare "valore di ritorno" - ad esempio, è abbastanza frequente che si invochi la chiamata alla funzione void .... – PiotrNycz