C++ 为什么使用取消引用的指针时EXPECT_调用测试意外通过?

C++ 为什么使用取消引用的指针时EXPECT_调用测试意外通过?,c++,unit-testing,pointers,googletest,googlemock,C++,Unit Testing,Pointers,Googletest,Googlemock,我刚刚开始使用GoogleTest和GoogleMock。阅读本示例测试一个依赖于海龟的Painter类: 真实对象-海龟.h class Turtle { public: virtual ~Turtle() {} virtual void PenDown() = 0; }; class MockTurtle : public Turtle { public: MOCK_METHOD0(PenDown, void()); }; class Painter { publ

我刚刚开始使用GoogleTest和GoogleMock。阅读本示例测试一个依赖于
海龟的
Painter
类:

真实对象-海龟.h

class Turtle {
public:
    virtual ~Turtle() {}
    virtual void PenDown() = 0;
};
class MockTurtle : public Turtle {
public:
    MOCK_METHOD0(PenDown, void());
};
class Painter {
public:
    Painter(Turtle *turtle){};
};
模拟对象-素甲鱼.h

class Turtle {
public:
    virtual ~Turtle() {}
    virtual void PenDown() = 0;
};
class MockTurtle : public Turtle {
public:
    MOCK_METHOD0(PenDown, void());
};
class Painter {
public:
    Painter(Turtle *turtle){};
};
测试中的代码-Painter.h

class Turtle {
public:
    virtual ~Turtle() {}
    virtual void PenDown() = 0;
};
class MockTurtle : public Turtle {
public:
    MOCK_METHOD0(PenDown, void());
};
class Painter {
public:
    Painter(Turtle *turtle){};
};
单元测试-测试.cpp

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

TEST(PainterTest, CanDrawSomething) {
    MockTurtle turtle;
    EXPECT_CALL(turtle, PenDown())
            .Times(AtLeast(1));
    Painter painter(&turtle);
}
由于从未调用
PenDown()
,因此此测试正确失败

但是,如果我将测试更改为使用指向
MockTurtle
的未引用指针,它将错误地通过

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

    Painter painter(turtle);
}
为什么在使用取消引用的指针时此测试会通过?我的代码中没有调用
PenDown()


对于更多的上下文,我想使用一个指向
MockTurtle
的指针,这样我就可以在测试夹具中初始化它,以便其他测试可以使用它。

除了@StoryTeller的优秀答案之外,我认为添加一些额外的背景会很有用,所以没有人会被这个问题所困扰

我使用CLion作为我的测试运行程序,因为在测试运行后发生的错误没有显示出来。从终端运行我的测试二进制显示:

./test_painter --gtest_filter=* --gtest_color=no
Running main() from gmock_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN      ] PainterTest.CanDrawSomething
[       OK ] PainterTest.CanDrawSomething (0 ms)
[----------] 1 test from PainterTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

/Users/donturner/PCode/workspace-kinetis/blinky/tests/test_painter.cpp:13: ERROR: this mock object (used in test PainterTest.CanDrawSomething) should be deleted but never is. Its address is @0x7fc06f402720.
ERROR: 1 leaked mock object found at program exit.
所以我忘了删除我的指针。我在测试结束时添加了以下行:

delete turtle; 
嘿,正确地进行测试失败:

$ ./test_painter --gtest_filter=* --gtest_color=no
Running main() from gmock_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN      ] PainterTest.CanDrawSomething
/Users/donturner/PCode/workspace-kinetis/blinky/tests/test_painter.cpp:13: Failure
Actual function call count doesn't match EXPECT_CALL(*turtle, PenDown())...
         Expected: to be called at least once
           Actual: never called - unsatisfied and active
[  FAILED  ] PainterTest.CanDrawSomething (0 ms)
[----------] 1 test from PainterTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] PainterTest.CanDrawSomething

 1 FAILED TEST

如果有人能告诉我为什么忘记删除指针会导致调用
PenDown()
,我会非常感兴趣

您不会删除指针

并不是说忘记删除它会导致推送
PenDown()
。该成员从未被呼叫过。但是将结果报告给框架的是
MockTurtle
析构函数

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

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


这只是GoogleMock的样板文件。

我使用的是最新版本的Google测试,它的工作情况与预期相符。尝试使用最新版本的Google Test我也使用最新版本的Google Test(从github获取)。您是否正在做一些特殊的工作来构建您的测试可执行文件?我的构建命令是:<代码> G++-i GoogleMoC/包含-我….. /源-L GoogleMoC+LGMOKCKEN TestPyPaTr.CPP -O TestJuffer-<代码>没有什么特别之处,但我使用Visual C++,并且这里两个测试都有兴趣,您在测试结束时有<代码>删除龟>代码>或者它和上面写的完全一样?是的,我在实例化painter的对象后使用delete删除了turtle,否则会导致内存泄漏,现在我可以复制这个问题了。听起来很有趣