2013-06-21 10 views
7

Ich habe eine Klasse, die einen Booleschen als Bezugsgröße nimmt und gibt eine ganze Zahl:Google Mock ByRef Methode

class Foo 
{ 
    public: 
    Bar my_bar; 
    virtual int myMethod(bool &my_boolean) = 0; 
} 

/*...*/ 

int Foo::myMethod(bool &my_boolean){ 
    if (my_bar == NULL){ 
    my_boolean = false; 
    return -1; 
    } 
    else{ 
    my_boolean = true; 
    return 0; 
    } 

} 

Und habe ich ein Mock für diese Klasse:

class MockFoo : public Foo 
{ 
    MOCK_METHOD1(myMethod,int(bool &my_boolean)); 
} 

Ich bin Probleme bei der Festlegung der Erwartungen für diese Art von Funktion haben, weil ich den Referenzwert und den Referenzparameter auf bestimmte Werte festlegen muss, um meine Komponententests richtig zu erstellen. Wie kann ich mit gmock diese Art von Funktion umgehen? Ich habe versucht, dem zu folgen, was ich dachte als die Lösung auf der Dokumentation:

using ::testing::SetArgPointee; 

class MockMutator : public Mutator { 
    public: 
    MOCK_METHOD2(Mutate, void(bool mutate, int* value)); 
    ... 
}; 
    ... 

MockMutator mutator; 
EXPECT_CALL(mutator, Mutate(true, _)) 
    .WillOnce(SetArgPointee<1>(5)); 

Aber entweder ich habe nicht das Beispiel, oder es war nicht für dieses case.Has jemand behandelt verstanden whith diese Art von Situation vor?

Vielen Dank im Voraus.

+0

Dann bekomme ich nicht, was ist deine Frage. Können Sie Ihre Probleme ausarbeiten? Der Code scheint für mich korrekt zu sein. Oder möchten Sie wissen, wie Sie die Erwartungswerte für den Referenzparameter analog setzen? 'ByRef()' wäre dafür völlig in Ordnung. –

+0

+1, das ist schwer zu bekommen aus den Beispielen des Kochbuchs. –

Antwort

6

Ihre Frage ist schwer zu bekommen! Die Beispiele von Google Mocks Kochbuch sind auch so.

Möchten Sie die Implementierung für Foo::myMethod() mit Ihnen Mock-Klasse wiederverwenden, oder möchten Sie nur die Nebenwirkungen (Rückgabewert und geändert durch Ref-Parameter) für bestimmte Anrufsituationen?

Eine Scheinklasse ist normalerweise dazu gedacht, Ihre Foo Klasse zu ersetzen/zu simulieren, nicht um sie direkt oder ihr Verhalten zu erben. Ich weiß nicht, ob die Art und Weise, wie Sie dieses Standardverhalten für eine reine Methode definieren, funktionieren wird, bezweifle das aber. Sie könnten dann einfach die = 0 weglassen. Der bessere Ansatz eine echte Schnittstelle Erklärung zu trennen wäre wie:

struct IFoo 
{ 
    virtual int myMethod(bool &my_boolean) = 0; 
    virtual ~IFoo() {} 
}; 

class Foo : public IFoo 
{ 
    // ... 
}; 

class MockFoo : public IFoo 
{ 
    MOCK_METHOD1(myMethod,int(bool &my_boolean)); 
}; 

Wenn Sie den letzteren Fall haben, sollten Sie mit testing::Return(value) und testing::SetArgReferee<N>(value) (festgestellt, dass in den sehr nützlich 'Cheat Sheet') aus.

Ihre Erwartung Anruf wie diese dann aussehen sollte:

MockFoo foo; 

// Expect call to myMethod() return -1 and set the by ref argument to true 
EXPECT_CALL(foo, myMethod(_)) 
    .WillOnce(DoAll(SetArgReferee<0>(true),Return(-1))); 

// Expect call to myMethod() return 0 and set the by ref argument to false 
EXPECT_CALL(foo, myMethod(_)) 
    .WillOnce(DoAll(SetArgReferee<0>(false),Return(0))); 

Wenn Sie wirklich Ihre ursprüngliche Klassen Logik wollen wiederzuverwenden für myMethod() einen Blick auf 'Delegating calls to a parent class' haben, resp. 'Delegating Calls to a Real Object'

+0

Sorry @ g-makulik Ich hatte das falsche Code-Snippet kopiert, das mit dieser Frage nicht verwandt war. Ich habe es jetzt korrigiert. –

+0

Entschuldigung, es hat mich ein wenig Zeit gekostet, um dein Problem herauszufinden. 'ByRef()' war der falsche Pfad für diesen Fall. –

+0

@RodrigoVasconcelos Nicht mehr interessiert? Löst das deine Probleme? –