谷歌模拟全局模拟对象内存泄漏
Google mock global mock object memory leak
我使用的是VS2005,C++使用google mock进行单元测试
我在单元测试中有一个全局自由函数,我使用以下代码来模拟自由函数:
NiceMock <MockA> mockObj;
struct IFoo {
virtual A* foo() = 0;
virtual ~IFoo() {}
};
struct FooMock : public IFoo {
FooMock() {}
virtual ~FooMock() {}
MOCK_METHOD0(foo, A*());
};
FooMock fooMock;
// foo() implementation
A* foo() {
return fooMock.foo();
}
在SetUp()
函数中,我在全局对象(如)上设置Experiences
EXPECT_CALL(fooMock,foo())
.Times(1)
.WillOnce(Return(&mockObj));
TEST(..., instA) {
// ...
}
在TearDown()
中,我删除了全局模拟对象fooMock
virtual TearDown(){
delete &fooMock;
}
当我运行代码时,我得到以下错误
错误:xyz.instA,内存泄漏
此外,
0个可用块中有0个字节
--1个正常块中的61个字节
在7个CRT块中有68个字节
0忽略块中有0个字节
0个客户端块中有0个字节
使用的最大数字:11025字节
分配总数:50602字节。
有人能告诉我这里发生了什么吗?如果我不删除fooMock
,我会得到错误"fooMock应该被删除,但从来没有被删除",或者检测到堆损坏
从错误中,我可以看出我的堆在某个地方处理不当,但我找不到重点。我也试着一步一步地调试它。
一些帮助会非常好!:)
正如Ian所说:
Googlemock/googletest期望mock可以在测试的主体中定义,也可以在测试夹具类中定义。
它背后的想法在食谱中有解释:
当它被破坏时,你的友好模拟对象会自动验证对它的所有期望都得到了满足,如果没有,就会产生谷歌测试失败。这很方便,因为它让你少了一件需要担心的事情。也就是说,除非您不确定您的模拟对象是否会被销毁。
在您的案例中,fooMock是一个全局变量(正如您所说,它必须保持这种状态),因此在每次测试后,您只需要运行手动验证:
using ::testing::Mock;
TEST(..., instA)
{
ASSERT_TRUE(
Mock::VerifyAndClearExpectations(
&fooMock));
}
由于它是一个全局变量,您也可以执行以下操作:
Mock::AllowLeak(&fooMock);
Cookbook中的更多详细信息-强制验证和备忘单-验证和重置模拟:
问题似乎是您正在实例化FooMock的全局实例。Googlemock/googletest期望mock可以在测试的主体中定义,也可以在测试夹具类中定义。
在上面的例子中,您只需在测试中实例化fooMock:
TEST(..., instA) {
FooMock fooMock;
// ...
}
所以我偶然发现了这个问题,想不出办法。但作为一名软件工程师,我需要找到一个解决方案。我就是这么做的。
假设您想模拟一个队列。要模拟的一个函数是出列。我假设您希望将整数出列以保持简单,因为我想演示如何在没有内存泄漏的情况下制作全局mock。
class QueueInterface {
public:
virtual ~QueueInterface() {};
virtual int dequeue() = 0;
};
class QueueMock : public QueueInterface {
public:
virtual ~QueueMock() {};
MOCK_METHOD(int, dequeue, (), (override));
};
// Instead of a global object, have a global pointer
QueueMock *globalQueue;
class TestFixture : public ::testing::Test {
protected:
QueueMock mockedQueue;
void SetUp() {
globalQueue = &mockedQueue; // Point the global pointer to this queue
}
void TearDown() {
globalQueue = NULL;
}
}
// Now you can use this global queue pointer in free function or
// C style functions and override the existing implementations.
// This way you can mock a global object.
int dequeueFromQueue() {
return globalQueue->dequeue();
}
TEST_F(TestFixture, DEQUEUE_TEST) {
// Write your test here to use global queue pointer
// Deref pointer to get mocked object
EXPECT_CALL(*globalQueue, dequeue);
}
这样,每当执行新的测试时,就会分配成员变量mockedQueue,然后在测试结束时解除分配。globalQueue每次都会指向每个测试的成员实例。
希望这能有所帮助!:)
我遇到了同样的问题,下面是解决方案(不确定内部到底发生了什么,因为全局mock obj最终会被销毁)。
std::unique_ptr ptrMockObj(新FooMock());
在测试用例结束时,删除mock obj ptr
测试(…,instA){。。。ptrMock.Object.reset()}
- valgrind-hellgrind与泄漏检查的结果不同
- 如何使用Google Mock来模拟gettimeofday()
- G锁定铸造到基础上会释放模拟行为
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 落砂模拟碰撞检测C++和SFML
- 在gtest.中使用fff.h模拟系统API
- 谷歌模拟和覆盖关键字
- 用C#中的并集模拟C++嵌套结构
- 尽管遵循了规则,内存泄漏在哪里
- 在同一模拟中使用静脉和静脉_ inet内容时出现运行时错误
- 为什么调用堆栈数组会导致内存泄漏
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- 我写了一个C++程序来模拟Enigma机器.我没有得到输出
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 谷歌模拟全局模拟对象内存泄漏
- 在Visual Studio中模拟一个简单的内存泄漏,结果有点混乱
- Google Mock:在程序出口处发现泄漏的模拟对象