Я дразнил класс Черепаха ...
Как именно вы дразнить его?
... но как я могу проверить doSomething()
метод (например, с EXPECT_CALL
), когда объект черепахи создается локально? Возможно ли без модификации класса Painter?
(выделено мной)
Прямой Ответ: Нет.
Вы не можете волшебным образом вводить макет вместо реального экземпляра , который используется в другом классе без развязки через интерфейс.
Вы должны иметь что-то вроде следующего кода вместо:
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);
};
Обеспечить реальной реализации вышеуказанных деклараций в отдельном прозрачны nslation.
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);
// ...
}
Вы можете альтернативно пройти интерфейс ITurtle
функции 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
}
Почему бы не проверить DoSomething и класс Черепаха в явном виде, а не с помощью тестов для Painter ? –
Метод DrawSomething имеет больше инструкций, я хочу нарисовать прямоугольник, используя несколько методов черепахи, например move(), turn(), penDown() и т. Д., И я хочу проверить, правильно ли они вызываются при вызове DrawSomething. – mcjay
Ну, насмешливые классы должны общаться через интерфейсы. Вы должны ввести интерфейс 'ITurtle' (абстрактный класс), который передается' void Painter :: DrawSomething() 'или удерживается' Painter' в качестве ссылочной переменной-члена. –