Google Mock:在程序退出时发现泄漏的模拟对象?

发布于 2024-11-18 08:37:31 字数 1960 浏览 3 评论 0原文

当我按如下方式定义测试时,它会起作用。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寻找一个思念的角度 2024-11-25 08:37:31

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.

灯下孤影 2024-11-25 08:37:31

我想我已经将错误追溯到 MyWrapperClass 的析构函数,它在传递给构造函数的对象上调用全局/静态函数 Destroy (第 3 方)。由于我传入的对象是假的,因此可能会因某种原因导致 Destroy 失败。所以问题是我该如何解决这个问题?在本例中,MyWrapperClass 是正在测试的对象,因此我不想修改它或模拟它。我想我必须找到一种方法来模拟函数 Destroy。如果我发现如何,会报告回来。

I think I have traced the error to the destructor of MyWrapperClass which calls a global/static function Destroy (3rd party) on the object passed into the constructor. Since the object I pass in is a fake, it probably causes Destroy 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 function Destroy. Will report back if I find out how.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文