使用包含模拟接口的 unique_ptr 使用依赖项注入时出现内存泄漏警告
Memory leak warning when using dependency injection using a unique_ptr containing a mocked interface
我的主要问题是关于特定的 gmock 错误,但要提供一些背景知识。我一直在做一个更大的项目,在这个项目中我有相同接口的不同实现。我希望能够使用接口实例化 class 并选择它必须使用的接口实现(在创建 class 实例时)。接口不共享,接口的每个实例仅供一个 class 实例使用。为此,我使用依赖注入并将接口实例存储在 unique_ptr 中。这正常工作并给了我想要的行为。为了对一些 class 进行单元测试,我使用 gmock 来模拟接口,然后将模拟接口注入到我的 class 待测中。令我惊讶的是,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();
}
测试通过但产生警告:
ERROR: this mock object (used in test test.test) should be deleted but never is. Its address is @0122CA60.
ERROR: 1 leaked mock object found at program exit. Expectations on a mock object are verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock.
Process finished with exit code 1
我的问题是2折。 1 为什么会泄漏内存 2 我应该如何改进我的设计?请注意,示例中未显示依赖项注入。将指针分配给接口将是一个构造函数,它将指针移动到 class 并从接口的实现中抽象出来。
std::unique_ptr<Base> base = std::move(mock);
是发生内存泄漏的地方:当 base
被销毁时,*base
将作为 Base
而不是 Mock
被销毁。
最好的解决方法是添加一个虚拟析构函数 (virtual ~Base() = default;
),您应该为具有任何其他虚拟成员的结构添加虚拟析构函数。
我的主要问题是关于特定的 gmock 错误,但要提供一些背景知识。我一直在做一个更大的项目,在这个项目中我有相同接口的不同实现。我希望能够使用接口实例化 class 并选择它必须使用的接口实现(在创建 class 实例时)。接口不共享,接口的每个实例仅供一个 class 实例使用。为此,我使用依赖注入并将接口实例存储在 unique_ptr 中。这正常工作并给了我想要的行为。为了对一些 class 进行单元测试,我使用 gmock 来模拟接口,然后将模拟接口注入到我的 class 待测中。令我惊讶的是,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();
}
测试通过但产生警告:
ERROR: this mock object (used in test test.test) should be deleted but never is. Its address is @0122CA60.
ERROR: 1 leaked mock object found at program exit. Expectations on a mock object are verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock. Process finished with exit code 1
我的问题是2折。 1 为什么会泄漏内存 2 我应该如何改进我的设计?请注意,示例中未显示依赖项注入。将指针分配给接口将是一个构造函数,它将指针移动到 class 并从接口的实现中抽象出来。
std::unique_ptr<Base> base = std::move(mock);
是发生内存泄漏的地方:当 base
被销毁时,*base
将作为 Base
而不是 Mock
被销毁。
最好的解决方法是添加一个虚拟析构函数 (virtual ~Base() = default;
),您应该为具有任何其他虚拟成员的结构添加虚拟析构函数。