为什么谷歌测试/模拟显示 std::unique_ptr 泄露的模拟对象错误?

Why does Google Test/Mock show leaked mock object error by std::unique_ptr?

本文关键字:模拟 对象 ptr 错误 unique 测试 谷歌 显示 为什么 std      更新时间:2023-10-16

假设有Bar对象使用Foo对象。所有权是排他性的,因此Bar在其构造函数中作为std::unique_ptrFoo。我想用谷歌测试框架测试Bar,所以我做了一个以下代码:

using namespace testing;
class Foo
{
public:
virtual int F() = 0;
};
class Bar
{
public:
Bar(std::unique_ptr<Foo>&& foo) : m_foo(std::move(foo))
{
}
int B()
{
return m_foo->F();
}
private:
std::unique_ptr<Foo> m_foo;
};
class MockFoo : public Foo
{
public:
MOCK_METHOD0(F, int());
};
class BarTest : public Test
{
};
TEST_F(BarTest, Test1)
{
auto mock_foo = std::make_unique<MockFoo>();
ON_CALL(*mock_foo, F()).WillByDefault(Return(1));
Bar bar(std::move(mock_foo));
auto val = bar.B();
EXPECT_THAT(val, 1);
}

测试运行良好,但我收到以下错误:

。test.cpp:293:错误:这个模拟对象(在测试 BarTest.Test1 中使用(应该被删除,但永远不会删除。它的地址是@0x1c7c590。 错误:在程序退出时发现 1 个泄漏的模拟对象。

我认为Google测试认为我没有销毁mock_foo但是它没有看到它不必在此处删除,因为它已被移动。测试是安全的,因为对象本身是相同的,只是所有权发生了变化(这是我的意图(。

我的假设正确吗?如果是,如何禁止显示此错误消息?我不,内存泄漏在哪里?

问题是Foo没有虚拟析构函数。 因此,std::unique_ptr<Foo>不会调用派生类的析构函数,而只是调用Foo的析构函数。

class Foo
{
public:
virtual ~Foo() = default;
virtual int F() = 0;
};

请参阅何时使用虚拟析构函数?如果基类Foo具有虚函数,则它应具有虚拟析构函数或非公共析构函数。