为什么 Google Test/Mock 显示 std::unique_ptr 泄漏的模拟对象错误?
Why does Google Test/Mock show leaked mock object error by std::unique_ptr?
假设有 Bar
个对象使用了 Foo
个对象。所有权是独占的,因此 Bar
在其构造函数中将 Foo
作为 std::unique_ptr
获取。我想用Google测试框架测试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>
因此不会调用派生的 class 的析构函数,只是 Foo
的析构函数。
class Foo
{
public:
virtual ~Foo() = default;
virtual int F() = 0;
};
参见When to use virtual destructors?如果基classFoo
有虚函数,它应该有虚析构函数或非public析构函数。
假设有 Bar
个对象使用了 Foo
个对象。所有权是独占的,因此 Bar
在其构造函数中将 Foo
作为 std::unique_ptr
获取。我想用Google测试框架测试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>
因此不会调用派生的 class 的析构函数,只是 Foo
的析构函数。
class Foo
{
public:
virtual ~Foo() = default;
virtual int F() = 0;
};
参见When to use virtual destructors?如果基classFoo
有虚函数,它应该有虚析构函数或非public析构函数。