谷歌模拟全局模拟对象内存泄漏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谷歌模拟全局模拟对象内存泄漏相关的知识,希望对你有一定的参考价值。

我正在使用VS2005和C ++进行使用谷歌模拟的单元测试。 我在单元测试中有一个全局自由函数,我使用以下代码来模拟自由函数:

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()函数中,我在全局对象上设置了Expectations

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应该删除但永远不会”,或检测到堆损坏。 从错误中,我可以看到我的堆被错误处理,但我找不到重点。我也试图一步一步地调试它。

一些帮助真的很棒! :)

答案

看起来问题是您正在实例化FooMock的全局实例。 Googlemock / googletest期望模拟在测试体内或测试夹具类中定义。

在上面的示例中,您只需在测试中实例化fooMock:

TEST(..., instA) {

    FooMock fooMock;
    // ...
}
另一答案

正如Ian所说:

Googlemock / googletest期望模拟在测试体内或测试夹具类中定义。

它背后的想法在Cookbook中解释:

当它被销毁时,友好的模拟对象将自动验证对它的所有期望是否已经满足,如果没有,将生成Google Test失败。这很方便,因为它让您不必担心。也就是说,除非你不确定你的模拟对象是否会被销毁。

在你的情况下,fooMock是一个全局变量(正如你所说它必须保持这种方式)所以在每次测试之后你只需要运行手动验证:

    using ::testing::Mock;

    TEST(..., instA) 
    {
       ASSERT_TRUE(
           Mock::VerifyAndClearExpectations(
            &fooMock));
    }

既然它是一个全局变量,你也可以这样做:

Mock::AllowLeak(&fooMock);

Cookbook - Forcing a VerificationCheatSheet - Verifying and Resetting a Mock的更多细节:

以上是关于谷歌模拟全局模拟对象内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

线上问题排查内存泄漏排查(模拟真实环境)

AudioToolbox 库 AVAudioPlayer 中的内存泄漏

iphone App中的内存泄漏

如何使用模块化代码片段中的LeakCanary检测内存泄漏?

google-map 片段应用程序在模拟器中崩溃后打开 WebView 活动

仪器在模拟器上发现泄漏,但在设备上没有