Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Google Test/Mock show leaked mock object error by std::unique_ptr?

Let's assume that there is Bar object which uses a Foo object. The ownership is exclusive, so Bar gets Foo as a std::unique_ptr in its constructor. I would like to test Bar with Google Test framework, so I made a following code:

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);
}

The test runs well but I got the following error:

...test.cpp:293: ERROR: this mock object (used in test BarTest.Test1) should be deleted but never is. Its address is @0x1c7c590. ERROR: 1 leaked mock object found at program exit.

I think Google Test thinks that I have not destroyed mock_foo but it does not see that it does not have to be deleted here because it has been moved. The test is safe because the object itself is the same, just the ownership has changed (which is my intention).

Is my assumption correct? If yes, how can I suppress this error message? I no, where is the memory leak?

like image 888
Tibor Takács Avatar asked May 23 '18 18:05

Tibor Takács


1 Answers

The problem is that Foo does not have a virtual destructor. std::unique_ptr<Foo> thus won't be calling the derived class's destructor, just Foo's destructor.

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

See When to use virtual destructors? If a base class Foo has virtual functions, it should either have a virtual destructor or a non-public destructor.

like image 59
Justin Avatar answered Sep 20 '22 00:09

Justin