2012-12-18 11 views
30

Non capisco la differenza tra ON_CALL e EXPECT_CALL quando lo utilizzo per specificare l'azione predefinita.gmock impostazione azioni predefinite/ON_CALL vs. EXPECT_CALL

Finora ho notato/imparato ci sono due modi per regolare l'azione predefinita di un mock:

ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01)); 

o

EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01)); 

Potrebbe qualcuno mi spieghi:

  • La differenza tra i due metodi
  • Gli alti e bassi di ognuno
  • Quando è opportuno usarli (che tipo di configurazione ...)

risposta

29

Ci sono differenze sottili ma significative tra le due affermazioni. EXPECT_CALL imposta le aspettative sulle chiamate simulate. Scrivendo

EXPECT_CALL(mock, methodX(_)).WillRepeatedly(do_action); 

dice gMock che methodX può essere chiamato su mock un numero illimitato di volte con argomenti, e, quando lo è, mock si esibirà do_action. D'altra parte,

ON_CALL(mock, methodX(_)).WillByDefault(do_action); 

dice gMock che ogni volta che viene invocato methodX su mock, dovrebbe svolgere do_action. Questa funzione è utile in uno scenario in cui devi scrivere molte aspettative sulla tua simulazione e la maggior parte/tutte devono specificare la stessa azione, specialmente se è complessa. È possibile specificare tale azione in ON_CALL e quindi scrivere EXPECT_CALL s senza specificare esplicitamente l'azione. Per esempio.,

ON_CALL(mock, Sign(Eq(0), _)) 
    .WillByDefault(DoAll(SetArgPointee<1>("argument is zero"), Return(0))); 
ON_CALL(mock, Sign(Gt(0), _)) 
    .WillByDefault(DoAll(SetArgPointee<1>("argument is positive"), Return(1))); 
ON_CALL(mock, Sign(Lt(0), _)) 
    .WillByDefault(DoAll(SetArgPointee<1>("argument is negative"), Return(-1))); 

Ora, se si deve scrivere un sacco di EXPECT_CALL s, voi non deve mock 's specificare il comportamento ogni volta:

EXPECT_CALL(mock, Sign(-4, _)); 
EXPECT_CALL(mock, Sign(0, _)); 
EXPECT_CALL(mock, Sign(1, _)).Times(2); 
EXPECT_CALL(mock, Sign(2, _)); 
EXPECT_CALL(mock, Sign(3, _)); 
EXPECT_CALL(mock, Sign(5, _)); 

In un altro esempio, supponendo che i rendimenti Sign int, se si scrive

ON_CALL(mock, Sign(Gt(0), _)).WillByDefault(Return(1)); 
EXPECT_CALL(mock, Sign(10, _)); 

la chiamata mock.Sign(10) tornerà 1 come ON_CALL fornisce comportamento predefinito per un chiamata specificata da EXPECT_CALL. Ma se si scrive

EXPECT_CALL(mock, Sign(Gt(0), _).WillRepeatedly(Return(1)); 
EXPECT_CALL(mock, Sign(10, _)); 

l'invocazione di mock.Sign(10, p) tornerà 0. sarà abbinato contro la seconda aspettativa. Tale aspettativa non specifica alcuna azione esplicita e gMock genererà un'azione predefinita per esso. L'azione predefinita consiste nel restituire un valore predefinito del tipo restituito, che è 0 per int. La prima aspettativa sarà totalmente ignorata in questo caso.

7
ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01)); 
EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01)); 

Come hai detto, queste due linee stanno facendo esattamente la stessa cosa, quindi non ci sono differenze affatto. Utilizzare in entrambi i modi per impostare un'azione predefinita come preferisci.

Tuttavia, c'è una differenza logica:

  • ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01)); significa che il metodo può essere chiamato, e se ciò accade, ogni chiamata tornerà 0x01
  • EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01)); significa che si prevede che il metodo sarà essere chiamato, e ogni chiamata tornerà 0x01

a proposito, c'è un Setting default actions nella loro ch mangia foglio, che dice:

Per personalizzare l'azione predefinita per un particolare metodo, utilizzare ON_CALL():

ON_CALL(mock_object, method(matchers)) 
    .With(multi_argument_matcher) ? 
    .WillByDefault(action); 
+0

Ma sembra che quando provo a sovrascrivere l'azione predefinita definita in precedenza con EXPECT_CALL con ON_CALL, non funziona. Qualche idea? – Nicoretti

+2

@Nicoretti No, non funziona. Non sono nemmeno sicuro di cosa succederebbe se imposti entrambi. Forse in quel caso ne viene eseguito solo uno. A proposito il gtest ha una [sezione] (http://code.google.com/p/googlemock/wiki/CheatSheet#Setting_Default_Actions) che spiega come impostare un comportamento predefinito. –

+0

sì ho visto questo ma ero curioso e confuso per il fatto che EXPECT_CALL può essere usato per modificare il comportamento predefinito. E i documenti non dicono nulla sugli effetti collaterali/priorità ... quando li usano entrambi. – Nicoretti