Google Mock:在程序退出时发现泄漏的模拟对象?
当我按如下方式定义测试时,它会起作用。
TEST(MyService, WhenCalled_DoesTheRightThingTM) {
// Arrange
ThirdPartyClassFake stub;
EXPECT_CALL(stub, GetFirstName())
.WillRepeatedly(Return("Bob"));
// Act
std::string result = stub.GetFirstName();
// Assert
EXPECT_STREQ("Bob", result);
}
ThirdPartyClassFake 是我创建的谷歌模拟类。
当我添加将指向我的存根的指针传递给包装类的代码时,我收到泄漏内存错误:
TEST(MyService, WhenCalled_DoesTheRightThingTM) {
// Arrange
ThirdPartyClassFake stub;
EXPECT_CALL(stub, GetFirstName())
.WillRepeatedly(Return("Bob"));
// Act
MyWrapperClass wrapper(&stub);
std::string result = stub.GetFirstName();
// Assert
EXPECT_STREQ("Bob", result);
}
错误是:
1> [ RUN ] MyService.WhenCalled_DoesTheRightThingTM
1>unknown file : error : SEH exception with code 0xc0000005 thrown in the test body.
1> [ FAILED ] MyService.WhenCalled_DoesTheRightThingTM (1 ms)
1>c:\myfile.cpp(17): error : this mock object (used in test
MyService.WhenCalled_DoesTheRightThingTM) should be deleted but never is.
Its address is @0028E40C.
1>EXEC : error : 1 leaked mock object found at program exit.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5):
error MSB3073: The command "C:\MyProject.Tests.exe
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5):
error MSB3073: :VCEnd" exited with code 1.
不确定它是否相关,但我应该添加来自第三方抽象的 ThirdPartyClassFake
子类类(我无法控制)具有所有虚拟方法,但没有虚拟析构函数。它还使用 Microsoft 特定的属性 __declspec(novtable)
进行声明。
我认为问题可能是由于缺少虚拟析构函数,如 Google 模拟常见问题解答。但我相信,如果这是问题所在,那么第一次测试也应该失败。
如何修复/解决此错误?
When I define my test as follows it works.
TEST(MyService, WhenCalled_DoesTheRightThingTM) {
// Arrange
ThirdPartyClassFake stub;
EXPECT_CALL(stub, GetFirstName())
.WillRepeatedly(Return("Bob"));
// Act
std::string result = stub.GetFirstName();
// Assert
EXPECT_STREQ("Bob", result);
}
ThirdPartyClassFake is a google mock class I created.
When I add code that passes a pointer to my stub to a wrapper class I get a leaked memory error:
TEST(MyService, WhenCalled_DoesTheRightThingTM) {
// Arrange
ThirdPartyClassFake stub;
EXPECT_CALL(stub, GetFirstName())
.WillRepeatedly(Return("Bob"));
// Act
MyWrapperClass wrapper(&stub);
std::string result = stub.GetFirstName();
// Assert
EXPECT_STREQ("Bob", result);
}
The error is:
1> [ RUN ] MyService.WhenCalled_DoesTheRightThingTM
1>unknown file : error : SEH exception with code 0xc0000005 thrown in the test body.
1> [ FAILED ] MyService.WhenCalled_DoesTheRightThingTM (1 ms)
1>c:\myfile.cpp(17): error : this mock object (used in test
MyService.WhenCalled_DoesTheRightThingTM) should be deleted but never is.
Its address is @0028E40C.
1>EXEC : error : 1 leaked mock object found at program exit.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5):
error MSB3073: The command "C:\MyProject.Tests.exe
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5):
error MSB3073: :VCEnd" exited with code 1.
Not sure if it's relevant but I should add that ThirdPartyClassFake
subclasses from a 3rd party abstract class (which I have no control over) with all virtual methods but no virtual destructor. Also it is declared with the Microsoft-specific attribute __declspec(novtable)
.
I thought the issue might be with the lack of a virtual destructor as described in the Google Mock FAQ. However I believe if that was the issue the first test should fail too.
How do I fix/workaround this error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
0xc0000005 是内存中的访问冲突。如果您没有使用正确的开关编译代码,则可能会引发此 SEH 异常,并且无法正确调用析构函数。
0xc0000005 is Access Violation, from memory. What's likely is that this SEH exception was thrown and the destructor wasn't called properly if you didn't compile the code with the right switches.
我想我已经将错误追溯到 MyWrapperClass 的析构函数,它在传递给构造函数的对象上调用全局/静态函数 Destroy (第 3 方)。由于我传入的对象是假的,因此可能会因某种原因导致
Destroy
失败。所以问题是我该如何解决这个问题?在本例中,MyWrapperClass
是正在测试的对象,因此我不想修改它或模拟它。我想我必须找到一种方法来模拟函数Destroy
。如果我发现如何,会报告回来。I think I have traced the error to the destructor of
MyWrapperClass
which calls a global/static functionDestroy
(3rd party) on the object passed into the constructor. Since the object I pass in is a fake, it probably causesDestroy
to fail for one reason or another. So the question is how do I work around this? In this case,MyWrapperClass
is the object under test so I do not want to modify it or mock it out. I guess I have to find a way to mock the functionDestroy
. Will report back if I find out how.