使用取消引用的指针时,为什么 EXPECT_CALL 测试会意外通过?

don*_*ner 3 c++ unit-testing pointers googletest googlemock

我刚刚开始使用 GoogleTest 和 GoogleMock。阅读“for dummies”文档,该示例测试了一个Painter依赖于以下内容的类Turtle

真实对象 - Turtle.h

class Turtle {
public:
    virtual ~Turtle() {}
    virtual void PenDown() = 0;
};
Run Code Online (Sandbox Code Playgroud)

模拟对象-mock-turtle.h

class MockTurtle : public Turtle {
public:
    MOCK_METHOD0(PenDown, void());
};
Run Code Online (Sandbox Code Playgroud)

测试中的代码 - Painter.h

class Painter {
public:
    Painter(Turtle *turtle){};
};
Run Code Online (Sandbox Code Playgroud)

单元测试 - test_painter.cpp

这是为了测试该turtle.PenDown()方法是否是从Painter构造函数中调用的。

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

该测试正确失败,因为PenDown()从未被调用。

但是,如果我将测试更改为使用取消引用的指针,则会错误地MockTurtle通过。

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

    Painter painter(turtle);
}
Run Code Online (Sandbox Code Playgroud)

为什么使用取消引用的指针时此测试能够通过?我的代码中没有任何地方被PenDown()调用。

对于更多上下文,我想使用一个指针,MockTurtle以便我可以在测试装置中初始化它,以便其他测试可以使用它。

Sto*_*ica 5

您不会删除指针。

并不是说忘记删除它就会导致被PenDown()推送。该成员永远不会被调用。但将结果报告给框架的是它的析构函数。MockTurtle

当你泄漏它时,不会有任何报告。该框架认为您运行了一个空测试(它空洞地通过),因为它没有得到任何反馈。

turtle是一个具有自动存储持续时间的对象(不是指针)时,它的析构函数会在作用域退出时自动调用。这就是报告错误的原因。

这只是使用RAII作为样板的 GoogleMock。