2016-04-27 23 views
5

Ho iniziato a utilizzare le librerie googletest e googlemock e ho un problema che non riesco a risolvere. Ho un codice simile a questa:C++, Googlemock - test dell'oggetto locale

class Painter 
{ 
    public: 
    void DrawSomething(); 
}; 

void Painter::DrawSomething() 
{ 
    Turtle turtle; 
turtle.doSomething(); 
} 

main() 
{ 
    Painter p; 
    p.DrawSomething(); 
} 

ho preso in giro la classe della tartaruga, ma come faccio a testare il metodo doSomething() (per esempio con EXPECT_CALL) quando viene creato localmente l'oggetto della tartaruga? È possibile senza modificare la classe Painter?

Grazie per le risposte.

+0

Perché non prova doSomething e la classe della tartaruga in modo esplicito, piuttosto che attraverso test per Painter ? –

+0

Il metodo DrawSomething ha più istruzioni, voglio disegnare un rettangolo usando pochi metodi di tartaruga per esempio move(), turn(), penDown() ecc. E voglio test se sono chiamati correttamente quando viene chiamato DrawSomething. – mcjay

+0

Bene, le classi di sdegno devono comunicare tramite interfacce. Dovresti introdurre un'interfaccia 'ITurtle' (classe astratta), che viene passata a' void Painter :: DrawSomething() 'o tenuta da' Painter' come variabile membro di riferimento. –

risposta

3

ho preso in giro la classe della tartaruga ...

Come esattamente hai fatto beffe di esso?

... ma come faccio a testare doSomething() metodo (per esempio con EXPECT_CALL) quando si crea l'oggetto della tartaruga a livello locale? È possibile senza modificare la classe Painter?
(sottolineatura mia)

La risposta semplice è: No.

Non è possibile iniettare magicamente una simulazione anziché una istanza reale utilizzata in un'altra classe senza disaccoppiarsi tramite un'interfaccia.


si dovrebbe avere qualcosa di simile al seguente codice invece:

struct ITurtle { 
    virtual void PenUp() = 0; 
    virtual void PenDown() = 0; 
    virtual void TurnLeft(double degrees) = 0; 
    virtual void Move(double distance) = 0; 
    // ... 
    virtual ~ITurtle() {} 
}; 

struct TurtleMock : ITurtle { 
    // Mock method declarations 
    MOCK_METHOD0(PenUp, void()); 
    MOCK_METHOD0(PenDown, void()); 
    MOCK_METHOD1(TurnLeft, void (double)); 
    MOCK_METHOD1(Move, void (double)); 
}; 

class Turtle : public ITurtle { 
public: 
    void PenUp(); 
    void PenDown(); 
    void TurnLeft(double degrees); 
    void Move(double distance); 
}; 

Fornire il vero implementazione per le dichiarazioni di cui sopra in una Tra separata unità nazionale.


class Painter { 
public: 
    Painter(ITurtle& turtle) : turtle_(turtle) {} 
    void DrawSomething(); 
private: 
    ITurtle& turtle_; 
}; 

void Painter::DrawSomething() { 
    turtle_.PenDown(); 
    turtle_.TurnLeft(30.0); 
    turtle_.Move(10.0); 
    turtle_.TurnLeft(30.0); 
    turtle_.Move(10.0); 
    // ... 
} 

È possibile in alternativa, passare l'interfaccia ITurtle alla funzione DrawSomething():

class Painter { 
public: 
    void DrawSomething(ITurtle& turtle); 
}; 

void Painter::DrawSomething(ITurtle& turtle) { 
    turtle.PenDown(); 
    turtle.TurnLeft(30.0); 
    turtle.Move(10.0); 
    turtle.TurnLeft(30.0); 
    turtle.Move(10.0); 
    // ... 
} 

int main() { 
    NiceMock<TurtleMock> turtle; 
    Painter p(turtle); 
    // Painter p; <<< for the alternative solution 

    EXPECT_CALL(turtle,PenDown()) 
     .Times(1); 
    EXPECT_CALL(turtle,TurnLeft(_)) 
     .Times(2); 
    EXPECT_CALL(turtle,Move(_)) 
     .Times(2); 

    p.DrawSomething(); 
    // p.DrawSomething(turtle); <<< for the alternative solution 

} 
+0

Grazie mille per la spiegazione dettagliata, ho deriso la tartaruga esattamente come hai fatto in classe TurtleMock.Solo una domanda in più: diciamo che non ho un membro ITurtle nella classe Painter e l'oggetto Turtle viene creato solo nella funzione DrawSomething. Se voglio passare l'oggetto mock a questo metodo, l'unico modo è rendere DrawSomething (ITurtle e tartaruga)? – mcjay

+1

@mcjay _ "l'unico modo è di rendere' DrawSomething (ITurtle e tartaruga) '?" _ Sì, questa è l'alternativa. –

Problemi correlati