C++,Googlemock - 测试本地对象

mcj*_*jay 5 c++ unit-testing googletest googlemock gmock

我开始使用googletest和googlemock库,我遇到了一个无法解决的问题.我有一个像这样的代码:

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

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

main()
{
  Painter p;
  p.DrawSomething();
}
Run Code Online (Sandbox Code Playgroud)

我已经模拟了Turtle类,但是如果在本地创建了turtle对象,我该如何测试doSomething()方法(例如使用EXPECT_CALL)?是否可以不修改Painter类?

谢谢你的回答.

πάν*_*ῥεῖ 5

我嘲笑了海龟课...

您究竟如何嘲笑它?

...但是当本地创建turtle对象时,如何测试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() {}
};
Run Code Online (Sandbox Code Playgroud)
struct TurtleMock : ITurtle {
    // Mock method declarations
    MOCK_METHOD0(PenUp, void ());
    MOCK_METHOD0(PenDown, void ());
    MOCK_METHOD1(TurnLeft, void (double));
    MOCK_METHOD1(Move, void (double));
};
Run Code Online (Sandbox Code Playgroud)
class Turtle : public ITurtle {
public:
    void PenUp();
    void PenDown();
    void TurnLeft(double degrees);
    void Move(double distance);
};
Run Code Online (Sandbox Code Playgroud)

在单独的翻译单元中提供上述声明的实际实现。


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);
    // ...
}
Run Code Online (Sandbox Code Playgroud)

您也可以将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);
    // ...
}
Run Code Online (Sandbox Code Playgroud)
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

}
Run Code Online (Sandbox Code Playgroud)