2015-08-27 14 views
5

Sto utilizzando Google Mock per specificare un livello di compatibilità con un'API esterna. Nell'API esterna, ci sono diversi modi per fare alcune azioni, quindi voglio specificare che almeno una (o preferibilmente esattamente una) aspettativa da un insieme di aspettative sono soddisfatte. In pseudocodice, questo è quello che voglio fare:Google mock - almeno una delle molteplici aspettative

Expectation e1 = EXPECT_CALL(API, doFoo(...)); 
Expectation e2 = EXPECT_CALL(API, doFooAndBar(...)); 
EXPECT_ONE_OF(e1, e2); 
wrapper.foo(...); 

E 'possibile utilizzare Google Mock?

+0

'EXPECT_CALL (API, doFoo (_)) volte (1);.' Opere? –

+0

@ BЈовић Questo funziona fintanto che 'wrapper.foo()' chiama 'doFoo()', ma voglio testare anche se 'wrapper.foo()' non chiama 'doFoo()', a lungo come invece chiama 'doFooAndBar()'. – nemetroid

risposta

1

Questo è possibile farlo in due modi:

  1. con metodi personalizzati esecutore - creare una classe, con gli stessi metodi. E quindi utilizzare Invoke() per passare la chiamata a quell'oggetto
  2. utilizzando chiamata ordine parziale - creare aspettative diverse in diverse sequenze, come spiegato here

Con metodo personalizzato esecutore

Qualcosa di simile this:

struct MethodsTracker { 
    void doFoo(int) { 
    ++ n; 
    } 
    void doFooAndBar(int, int) { 
    ++ n; 
    } 
    int n; 
}; 

TEST_F(MyTest, CheckItInvokesAtLeastOne) { 
    MethodsTracker tracker; 
    Api obj(mock); 

    EXPECT_CALL(mock, doFoo(_)).Times(AnyNumber()).WillByDefault(Invoke(&tracker, &MethodsTracker::doFoo)); 
    EXPECT_CALL(mock, doFooAndBar(_,_)).Times(AnyNumber()).WillByDefault(Invoke(&tracker, &MethodsTracker::doFooAndBar)); 

    obj.executeCall(); 

    // at least one 
    EXPECT_GE(tracker.n, 1); 
} 

utilizzando chiamata ordine parziale

TEST_F(MyTest, CheckItInvokesAtLeastOne) { 
     MethodsTracker tracker; 
     Api obj(mock); 

     Sequence s1, s2, s3, s4; 

     EXPECT_CALL(mock, doFoo(_)).InSequence(s1).Times(AtLeast(1)); 
     EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s1).Times(AtLeast(0)); 

     EXPECT_CALL(mock, doFoo(_)).InSequence(s2).Times(AtLeast(0)); 
     EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s2).Times(AtLeast(1)); 

     EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s3).Times(AtLeast(0)); 
     EXPECT_CALL(mock, doFoo(_)).InSequence(s3).Times(AtLeast(1)); 

     EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s4).Times(AtLeast(1)); 
     EXPECT_CALL(mock, doFoo(_)).InSequence(s4).Times(AtLeast(0)); 

     obj.executeCall(); 
} 
+0

La chiamata all'ordine parziale sembra che potrebbe sfuggire di mano rapidamente, ma l'utilizzo del metodo personalizzato executor sembra una soluzione adeguata. – nemetroid