ich die Schildkröte Klasse verspottet haben ...
Wie genau hast du es verspotten?
... aber wie kann ich doSomething()
Verfahren (zum Beispiel mit EXPECT_CALL
), wenn das Objekt der Schildkröte testen lokal erstellt? Ist es möglich ohne Painter-Klasse zu ändern?
(Hervorhebung von mir)
Die einfache Antwort lautet: Nein .
Sie können statt einer realen Instanz, die in einer anderen Klasse ohne Entkopplung über eine Schnittstelle verwendet wird, keinen Mock injizieren.
Sie sollten stattdessen so etwas wie den folgenden Code haben:
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);
};
die echte Implementierung für die obigen Erklärungen in einem separaten tra Stellen Nslationseinheit.
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);
// ...
}
können Sie alternativ passieren die ITurtle
Schnittstelle zur DrawSomething()
Funktion:
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
}
Warum nicht testen doSomething und die Schildkröte Klasse explizit, anstatt durch Tests für Maler ? –
DrawSomething-Methode haben mehr Anweisungen, ich möchte ein Rechteck mit wenigen Turtle-Methoden wie move(), turn(), penDown() etc. und ich möchte testen, wenn sie richtig aufgerufen werden, wenn der DrawSomething aufgerufen wird. – mcjay
Nun, Spott Klassen müssen über Schnittstellen kommunizieren. Sie sollten eine 'ITurtle'-Schnittstelle (abstrakte Klasse) einführen, die an' void Painter :: DrawSomething() 'übergeben oder von' Painter' als Referenzelementvariable gehalten wird. –