You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:32:30