使用unique_ptr和std::move的Google Mock出现内存泄漏问题求助
Google Mock配合unique_ptr时的Mock泄漏问题
这是Google Mock使用unique_ptr对象导致内存泄漏问题的后续场景,被测类Bar的构造函数会获取unique_ptr<Foo>的所有权,相关代码如下:
class Foo { public: virtual void doFoo() { std::cout << "Foo" << std::endl; } }; class Bar { public: // 为测试注入Mock Foo Bar(std::unique_ptr<Foo> foo_) : foo_(std::move(foo_)) {} Bar() : foo_(std::make_unique<Foo>()) {} void doBar() { foo_->doFoo(); } private: std::unique_ptr<Foo> foo_; }; class MockFoo : public Foo { MOCK_METHOD(void, doFoo, (), (override)); }; class FooTest : public ::testing::Test { public: void SetUp() override { mockFoo = std::make_unique<NiceMock<MockFoo>>(); } std::unique_ptr<NiceMock<MockFoo>> mockFoo; NiceMock<MockFoo>* mockFooPtr; }; TEST_F(FooTest, foo) { using ::testing::NiceMock; // 故意设置不匹配的调用次数 EXPECT_CALL(*mockFoo, doFoo()).Times(2); mockFooPtr = mockFoo.get(); Bar bar(std::move(mockFoo)); bar.doBar(); EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(mockFooPtr)); }
运行上述测试用例会触发以下错误:
ERROR: this mock object (used in test FooTest.foo) should be deleted but never is. Its address is @0x5ccb272fba60. 3: 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.
可见VerifyAndClearExpectations并未生效,问题根源在于unique_ptr的所有权被转移给了Bar。如果将Bar修改为接收原始指针,则不会出现Mock泄漏错误:
class Bar { public: Bar(Foo* foo_) : foo_(foo_) {} void doBar() { foo_->doFoo(); } private: Foo* foo_; }; TEST_F(FooTest, foo) { using ::testing::NiceMock; // 设置匹配的调用次数 EXPECT_CALL(*mockFoo, doFoo()).Times(1); mockFooPtr = mockFoo.get(); Bar bar(mockFoo.get()); bar.doBar(); }
但生产代码要求必须使用std::move转移所有权,我尝试给Bar对象添加局部作用域,更新测试代码如下:
TEST_F(FooTest, foo) { // 故意设置不匹配的调用次数 EXPECT_CALL(*mockFoo, doFoo()).Times(2); mockFooPtr = mockFoo.get(); { Bar bar(std::move(mockFoo)); bar.doBar(); EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(mockFooPtr)); } }
但仍然出现Mock泄漏错误,恳请帮助!
内容的提问来源于stack exchange,提问作者Leonardo
相关产品推荐
相关产品推荐

