将GoogleMock与Boost::Shared Pointers一起使用时泄漏的Mock对象

Leaked Mock Objects when using GoogleMock together with Boost::Shared Pointers

本文关键字:泄漏 对象 Mock 一起 GoogleMock Boost Shared Pointers      更新时间:2023-10-16

对于这种特殊情况,我无法消除泄漏。

在执行测试时,我收到了Leaked Mock Objects的消息。具体信息:

ClassElementFixture.h:102:错误:这个模拟对象(在测试ClassElementFixture.initialize中使用)应该被删除,但永远不会被删除。它的地址是@0x940a650。

我标出了错误所指的那一行。这里是我代码的简化版本:

...
class ClassElementFixture: public ::testing::Test
{
    public:
        boost::shared_ptr<fesa::ClassElement> classElement_;
        boost::shared_ptr<fesa::DeviceElementMock> deviceElement_;
        ...
        void SetUp()
        {
            classElement_.reset(new fesa::ClassElement());
        }
        void TearDown()
        {
        }
        void initializeFake()
        {
            fesa::ParserElementFactoryMock factory;
            deviceElement_.reset(new fesa::DeviceElementMock());
            EXPECT_CALL(factory, createDeviceElement(_))
                        .WillOnce(Return(deviceElement1_));
            EXPECT_CALL(*deviceElement_, initialize(_));//Error refers to here
            classElement_->initialize(factory);
            EXPECT_TRUE(Mock::VerifyAndClearExpectations(deviceElement_.get()));
        }
}

我已经找到了为什么GoogleMock泄露了我的shared_ptr?

在Stack Overflow,这是相关的。然而,那里的建议并不能解决我的问题:X

为了至少抑制错误,我发现的唯一可能性是:

Mock::AllowLeak(deviceElement_.get());

然而,这不是一个非常干净的解决方案=)

那么,如何正确处理泄漏呢?

如果您使用智能指针,您仍然需要对所有权有一个清晰的概念,否则您可能会得到较差的性能、循环依赖关系和内存泄漏。

我建议智能指针的默认选择应该是unique_ptr,以获得唯一所有权,并使用原始指针作为观察者。

如果观察者可能比所有者活得更长,则为所有者移动到一个shared_ptr,为观察者移动到weak_ptr

只有当您没有一个明确的所有者时,才使用"共享"shared_ptr作为最后的手段,并注意循环依赖关系。

不要使用共享指针。或者,如果你真的必须使用它们,请确保它们回到0,并在测试结束时被销毁。

这是一个老问题,但我没有看到有人提到我刚刚找到的解决方案。

我看到了同样的错误,直到我在嘲笑的类中添加了一个虚拟析构函数。在您的情况下,请确保您在ParserElementFactoryMokk上有一个虚拟析构函数。有道理,因为如果没有虚拟析构函数,mock对象在超出范围时将不会释放其资源。