使用包含模拟接口的unique_ptr进行依赖项注入时出现内存泄漏警告



我的主要问题是关于一个特定的gmock错误,但要提供一些背景信息。我一直在做一个更大的项目,在这个项目中,我有相同接口的不同实现。我希望能够使用接口实例化一个类,并选择它必须使用的接口实现(在创建类实例时(。接口不是共享的,接口的每个实例只由一个类实例使用。为了做到这一点,我使用依赖注入,并将接口实例存储在unique_ptr中。这可以正常工作,并为我提供所需的行为。为了对一些类进行单元测试,我使用gmock模拟接口,然后将模拟接口注入到被测试的类中。令我惊讶的是,gmock告诉我,我有一个记忆泄漏,我不明白。一段简化的代码会产生相同的错误:

#include "gtest/gtest.h"
#include "gmock/gmock.h"
class Base {
public:
virtual int something() = 0;
};
class Mock : public Base {
public:
MOCK_METHOD(int, something, ());
};
class test : public ::testing::Test {
protected:
void SetUp() override {
mock = std::make_unique<Mock>();
EXPECT_CALL(*mock, something()).WillOnce(testing::Return(1));
}
std::unique_ptr<Mock> mock;
};

TEST_F(test, test) {
std::unique_ptr<Base> base = std::move(mock);
EXPECT_EQ(base->something(), 1);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

测试通过但产生警告:

错误:这个模拟对象(在test-test.test中使用(应该被删除,但永远不会被删除。它的地址是@0122CA60。

错误:在程序出口处发现1个泄漏的模拟对象。对模拟对象的期望在对象被破坏时得到验证。泄露mock意味着它的期望值没有得到验证,这通常是一个测试错误。如果您真的打算泄露mock,可以使用testing::mock::AllowLeak(mock_object(来抑制此错误,也可以使用false或stub来代替mock。进程结束,退出代码为1

我的问题有两个方面。1为什么内存被泄露,2我应该如何改进我的设计?请注意,该示例中没有显示依赖项注入。将指针分配给接口将是一个构造函数,它将指针移动到类中并从接口的实现中抽象出来。

std::unique_ptr<Base> base = std::move(mock);是发生内存泄漏的地方:当base被销毁时,*base将被销毁为Base,而不是Mock

最好的解决方案是添加一个虚拟析构函数(virtual ~Base() = default;(,对于具有任何其他虚拟成员的结构,应该使用该函数。

相关内容

  • 没有找到相关文章

最新更新