Google Mock Linux上的免费系统功能总是以内存泄漏结束
我试图模拟Linux标准库中的一个简单函数Google Mock Linux上的免费系统功能总是以内存泄漏结束,linux,memory-leaks,mocking,debian-based,Linux,Memory Leaks,Mocking,Debian Based,我试图模拟Linux标准库中的一个简单函数strerror()从错误号返回错误消息。这是我的库,具有模拟功能: ~$ cat mylib.c #include <string.h> #include <stdio.h> int myStrerror() { int error_number = 0; char* buffer = strerror(error_number); fprintf(stdout, "Returned str
strerror()
从错误号返回错误消息。这是我的库,具有模拟功能:
~$ cat mylib.c
#include <string.h>
#include <stdio.h>
int myStrerror()
{
int error_number = 0;
char* buffer = strerror(error_number);
fprintf(stdout, "Returned string = '%s'\n", buffer);
return 0;
}
#if defined (EXECUTABLE)
int main(int argc, char **argv)
{
return myStrerror();
}
#endif
~$ g++ -pedantic-errors -Wall -c mylib.c
这是它正常返回的结果:
~$ ./mylib.a
Returned string = 'Success'
运行测试可以得到以下结果:
~$ ./test_mylib.a
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MockTestSuite
[ RUN ] MockTestSuite.strerror
Returned string = 'mocked strerror function'
[ OK ] MockTestSuite.strerror (0 ms)
[----------] 1 test from MockTestSuite (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
test_mylib.cpp:32:错误:应删除此模拟对象(在test MockTestSuite.strerror中使用),但决不删除。其地址为@0x56114aa239e0。错误:在程序出口处发现1个泄漏的模拟对象。当模拟对象被破坏时,验证对该对象的期望。泄漏模拟意味着它的期望没有得到验证,这通常是一个测试错误。如果您确实打算泄漏模拟,可以使用testing::mock::AllowLeak(mock_对象)抑制此错误,也可以使用假或存根代替模拟
如何避免内存泄漏?问题是我们使用了系统库中的一个免费全局函数
strerror()
。它并不像Googlemock那样被界面模仿。所以我们不需要接口。我们必须用一个自由函数覆盖模拟函数,该函数必须是全局函数,才能与系统函数在同一范围内,因为它将替换它。这就是我们要做的:
strerrorMock strerrorMockObj;
char* strerror(int error_number) {
return strerrorMockObj.strerror(error_number);
}
这里mock的实例strerrorMockObj
也在全局范围内,可以在函数中调用。但很明显,Googletest无法删除错误消息中提到的全局模拟对象。我发现的一个解决方案是,像往常一样在测试宏中实例化mock对象,并存储指向它的全局指针,以便函数可以对其进行寻址:
strerrorMock* ptrStrerrorMockObj;
char* strerror(int error_number) {
return ptrStrerrorMockObj->strerror(error_number);
}
TEST(MockTestSuite, strerror)
{
strerrorMock strerrorMockObj;
ptrStrerrorMockObj = &strerrorMockObj;
...
}
然后,完整的测试程序(无内存泄漏)如下所示:
~$ cat test_strerror.cpp
#include "gtest/gtest.h"
#include "gmock/gmock.h"
int myStrerror();
class strerrorMock {
public:
MOCK_METHOD(char*, strerror, (int));
};
strerrorMock* ptrStrerrorMockObj;
char* strerror(int error_number) {
return ptrStrerrorMockObj->strerror(error_number);
}
TEST(MockTestSuite, strerror)
{
using ::testing::Return;
strerrorMock strerrorMockObj;
ptrStrerrorMockObj = &strerrorMockObj;
char mockedstr[] = "mocked strerror function";
EXPECT_CALL(strerrorMockObj, strerror(0))
.WillOnce(Return(mockedstr));
EXPECT_EQ(myStrerror(), 0);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
~$ cat test_strerror.cpp
#include "gtest/gtest.h"
#include "gmock/gmock.h"
int myStrerror();
class strerrorMock {
public:
MOCK_METHOD(char*, strerror, (int));
};
strerrorMock* ptrStrerrorMockObj;
char* strerror(int error_number) {
return ptrStrerrorMockObj->strerror(error_number);
}
TEST(MockTestSuite, strerror)
{
using ::testing::Return;
strerrorMock strerrorMockObj;
ptrStrerrorMockObj = &strerrorMockObj;
char mockedstr[] = "mocked strerror function";
EXPECT_CALL(strerrorMockObj, strerror(0))
.WillOnce(Return(mockedstr));
EXPECT_EQ(myStrerror(), 0);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}