Home > Back-end >  Memory leak warning when using dependency injection using a unique_ptr containing a mocked interface
Memory leak warning when using dependency injection using a unique_ptr containing a mocked interface

Time:12-30

My main question is about a specific gmock error but to provide some background. I have been working on a larger project where I have different implementations of the same interface. I want to be able to instantiate a class using the interface and choose which interface implementation it has to use (when creating the class instance). The interface is not shared and each instance of the interface is only used by one class instance. In order to do this I use dependency injection and I store the interface instance in a unique_ptr. This works properly and gives me the desired behavior. To unit test some the class I used gmock to mock the interface and then injected the mocked interface into my class under test. To my surprise gmock informed me that I had a memory leak which I do not understand. A simplified piece of code produces the same error:

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

The test passes but produces the warning:

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

My question is 2 fold. 1 why is the memory being leaked and 2 how should I improve my design? Note that the dependency injection is not shown in the example. Assigning the pointer to the interface would be a constructor which moves the pointer into the class and abstracts from the implementation of the interface.

CodePudding user response:

std::unique_ptr<Base> base = std::move(mock); is where the memory leak happens: *base will be destroyed as a Base, not a Mock, when base is destroyed.

The best fix is to add a virtual destructor (virtual ~Base() = default;), which you should have for a struct that has any other virtual members.

  • Related