How to make fun of malloc to return null in GMOCK?

I want to fake malloc in C ++ using the Gmock platform. Is it possible? I tried all possible ways. But did the class hosting this malloc implementation get a private constructor and destructor?

Is there a way we can directly mock malloc to return NULL?

+4
source share
3 answers

DeveloperLove,

first of all, mocking a standard library is never a good practice, and testing code at this level of granulation is an art for art's sake. You should note that from the very beginning, tests become part of the project, and if you want to keep them up to date (aka maininging working regression), you should think of their design in the same way as production code. In fact, tests are also code that must be maintained throughout the life of the project, and when reading, fixing, and finalizing, when the tests take too long, such a regression will be useless. Try to think of it as "documentation for life."

However, probably one of the ugliest ways to mock the standard C library is with a static hook and macros. Consider the following example:

#include <gtest/gtest.h> #include <gmock/gmock.h> #include <boost/bind.hpp> #include <boost/function.hpp> static boost::function<void*(size_t)> malloc_bridge; struct StdlibMock { StdlibMock() { malloc_bridge = boost::bind(&StdlibMock::mallocMock, this, _1); } MOCK_METHOD1(mallocMock, void*(size_t)); }; // struct Struct StdlibMock void* malloc_cheat(size_t size) { return malloc_bridge(size); } #define malloc malloc_cheat struct Sut { void f() { malloc(10); } }; struct TestWithMalloc : ::testing::Test { StdlibMock stdlibMock; }; // struct TestWithMalloc TEST_F(TestWithMalloc, ShouldMalloc10Bytes) { EXPECT_CALL(stdlibMock, mallocMock(10)) .WillOnce(::testing::Return(static_cast<void*>(0))); Sut sut; sut.f(); } #undef malloc 

Note that you cannot replace the mallocMock function name with a simple malloc due to the use of a preprocessor macro. Hope it was a little helpful.

+1
source
  • Wrap malloc
  • Pass the wrapper to the tested c'tor class in production code
  • Trick the shell (you can also create an interface over the wrapper and mock it)
  • Pass the layout to the c'tor class you are testing in your test code

     class I_mallocWrapper { public: virtual ~I_mallocWrapper() {} virtual void* myMalloc (size_t size) = 0; }; //wrapper to malloc class mallocWrapper : public I_mallocWrapper { public: virtual void* myMalloc (size_t size) {return malloc(size);} virtual ~mallocWrapper() {} mallocWrapper(){} }; //tested class with tested method that uses the wrapper class TestedClass { public: TestedClass(I_mallocWrapper* mallocW) { this->m_mallocWrapper = mallocW; } void testedMethod(size_t size) { m_mallocWrapper->myMalloc(size); } virtual ~TestedClass() {} private: I_mallocWrapper* m_mallocWrapper; }; //production code void main() { size_t size = 18; I_mallocWrapper* MW = new mallocWrapper; TestedClass* TC = new TestedClass(MW); TC->testedMethod(size); } //mock the wrapper class mockMallocWrapper : public I_mallocWrapper { public: MOCK_METHOD1(myMalloc, void*(size_t size)); }; //test code TEST(MallocTest,callMalloc) { size_t size = 18; I_mallocWrapper* MW = new mockMallocWrapper; TestedClass* TC = new TestedClass(MW); TC->testedMethod(size); EXPECT_CALL(MW, myMalloc(_)) .WillOnce(Return(NULL)) } 
0
source

glibcmock can help you make fun of malloc and other libc function.

 #include "got_hook.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include <mutex> #include <memory> struct MockMalloc { MOCK_METHOD1(Malloc, void *(size_t)); }; static MockMalloc *g_mock{nullptr}; static void *Malloc(size_t size) { return g_mock->Malloc(size); } static std::mutex g_test_mutex; TEST(MallocTest, ReturnNull) { std::lock_guard<std::mutex> lock(g_test_mutex); std::unique_ptr<MockMalloc> mock(g_mock = new MockMalloc()); testing::GotHook got_hook; ASSERT_NO_FATAL_FAILURE(got_hook.MockFunction("malloc", (void*)&Malloc);); // ... do your test here, for example: EXPECT_CALL(*g_mock, Malloc(testing::_)).WillOnce(testing::Return(nullptr)); EXPECT_EQ(nullptr, malloc(1)); } 
0
source

Source: https://habr.com/ru/post/1491531/


All Articles