【问题标题】:Why does Google Test/Mock show leaked mock object error by std::unique_ptr?为什么 Google 测试/模拟显示 std::unique_ptr 泄漏的模拟对象错误?
【发布时间】:2018-05-23 18:54:37
【问题描述】:

假设有一个使用Foo 对象的Bar 对象。所有权是独占的,所以Bar 在其构造函数中将Foo 作为std::unique_ptr。我想用谷歌测试框架测试Bar,所以我做了以下代码:

using namespace testing;

class Foo
{
  public:
    virtual int F() = 0;
};

class Bar
{
  public:
    Bar(std::unique_ptr<Foo>&& foo) : m_foo(std::move(foo))
    {
    }

    int B()
    {
        return m_foo->F();
    }

  private:
    std::unique_ptr<Foo> m_foo;
};

class MockFoo : public Foo
{
  public:
    MOCK_METHOD0(F, int());
};

class BarTest : public Test
{
};

TEST_F(BarTest, Test1)
{
    auto mock_foo = std::make_unique<MockFoo>();
    ON_CALL(*mock_foo, F()).WillByDefault(Return(1));

    Bar bar(std::move(mock_foo));

    auto val = bar.B();

    EXPECT_THAT(val, 1);
}

测试运行良好,但出现以下错误:

...test.cpp:293: 错误:这个模拟对象(在测试 BarTest.Test1 中使用)应该被删除,但永远不会。它的地址是@0x1c7c590。 错误:在程序退出时发现 1 个泄露的模拟对象。

我认为Google Test认为我没有销毁mock_foo但它没有看到它不必在这里删除,因为它已经被移动了。测试是安全的,因为对象本身是相同的,只是所有权发生了变化(这是我的意图)。

我的假设正确吗?如果是,我该如何抑制此错误消息?我没有,内存泄漏在哪里?

【问题讨论】:

  • @Justin 是的,确实如此,非常感谢。您能否将其添加为能够接受的答案?

标签: c++ c++11 googletest googlemock


【解决方案1】:

问题是Foo 没有虚拟析构函数。 std::unique_ptr&lt;Foo&gt; 因此不会调用派生类的析构函数,而只是调用Foo 的析构函数。

class Foo
{
  public:
    virtual ~Foo() = default;
    virtual int F() = 0;
};

参见When to use virtual destructors? 如果基类Foo 具有虚函数,则它应该具有虚析构函数或非公共析构函数。

【讨论】:

  • @谢谢,这就是解决方案。我不明白的是,如果一切都相同但Bar 接收纯指针(Foo*),为什么它会起作用?情况应该是一样的,但是没有出现错误信息。
  • @TiborTakács 不幸的是,我不知道 googletest 的泄漏检查是如何工作的。假设你写了new MockFoo,如果你写了delete m_foo,那将是未定义的行为。如果你没有写new,而是写了MockFoo mock_foo之类的东西,然后传入&amp;mock_foo,那完全可以预期
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多