C++, Googlemock - testing local object

I have mocked the Turtle class ...

How exactly did you mock it?

... but how can I test doSomething() method (for example with EXPECT_CALL) when the object of turtle is created locally? Is it possible without modifying Painter class?
(Emphasis mine)

The straightforward answer is: No.

You cannot magically inject a mock instead of a real instance used in another class without decoupling via an interface.


You should have something like the following code instead:

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);
};

Provide the real implementation for the above declarations in a separate translation unit.


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);
    // ...
}

You can alternatively pass the ITurtle interface to the DrawSomething() function:

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

}