Search code examples
c++unit-testingpointersgoogletestgooglemock

Why do EXPECT_CALL tests pass unexpectedly when using a dereferenced pointer?


I am just getting started with GoogleTest and GoogleMock. Reading the "for dummies" documentation the example tests a Painter class which depends on a Turtle:

Real object - Turtle.h

class Turtle {
public:
    virtual ~Turtle() {}
    virtual void PenDown() = 0;
};

Mock object - mock-turtle.h

class MockTurtle : public Turtle {
public:
    MOCK_METHOD0(PenDown, void());
};

Code under test - Painter.h

class Painter {
public:
    Painter(Turtle *turtle){};
};

Unit test - test_painter.cpp

This is intended to test whether the turtle.PenDown() method is called from the Painter constructor.

TEST(PainterTest, CanDrawSomething) {
    MockTurtle turtle;
    EXPECT_CALL(turtle, PenDown())
            .Times(AtLeast(1));
    Painter painter(&turtle);
}

This test correctly fails because PenDown() is never called.

But if I change the test to use a dereferenced pointer to MockTurtle it incorrectly passes.

TEST(PainterTest, CanDrawSomething) {
    MockTurtle *turtle = new MockTurtle();
    EXPECT_CALL(*turtle, PenDown())
            .Times(AtLeast(1));

    Painter painter(turtle);
}

Why does this test pass when using a dereferenced pointer? Nowhere in my code is PenDown() called.

For more context, I would like to use a pointer to MockTurtle so that I can initialise it in a test fixture so that other tests can use it.


Solution

  • You don't delete your pointer.

    And it's not that forgetting to delete it is going to result in PenDown() being pushed. The member is never called. But it's the destructor of MockTurtle that reports the results to the framework.

    When you leak it, nothing is reported. The framework thinks you ran an empty test (which vacuously passes), because it doesn't get any feedback.

    When turtle is an object (not a pointer), that has automatic storage duration, its destructor is called automatically at scope exit. That's why the error is reported.

    This is just GoogleMock utilizing RAII for the boilerplate.