Google Mock:可以使用全局模拟对象吗?

Geo*_* P. 6 c++ unit-testing mocking googletest gmock

在有关gmock 的所有文档中,我总是发现要在测试中实例化的模拟对象,如下所示:

TEST(Bim, Bam)
{
    MyMockClass myMockObj;
    EXPECT_CALL(MyMockObj, foo(_));
    ...
}
Run Code Online (Sandbox Code Playgroud)

因此,每次测试都会创建和销毁对象。我相信创建和销毁每个测试装置的对象也完全没问题。但我想知道是否也可以拥有模拟对象的文件全局实例,如下所示:

MyMockClass myMockObj;

TEST(Bim, Bam)
{
    EXPECT_CALL(MyMockObj, foo(_))
    ...
}
Run Code Online (Sandbox Code Playgroud)

我试过了,到目前为止我绝对没有问题,它似乎一切正常。但也许我应该知道什么?只是因为我偶然发现了这个问题,唯一的答案是:

...问题在于您正在实例化 FooMock 的全局实例。Googlemock/googletest 期望在测试主体内或测试夹具类内定义模拟。

但是我在文档或其他任何地方都找不到任何证实这一点的内容(我是否忽略了它?)。

谢谢,乔治

PS:我需要使用全局模拟实例的原因将是另一个讨论的主题(请参阅我的这篇帖子)。

Old*_*Fox 4

你可以,但这不是一个好主意。

这样做是违反隔离原则的UT。此违规可能会导致测试意外失败/通过。

Gtest使用假对象的析构函数来验证期望是否发生,这就是每个假对象将在测试主体或测试装置类中创建和释放的期望背后的原因。

如果您将假对象设置为全局,那么它不会在每个结束时释放UT,那么验证将不会执行,并且即使应该失败,测试也会通过。UT更重要的是,当您一起执行所有测试时,您的某些测试可能会失败/失败;在一个测试中,您期望该方法x不会调用,而在另一测试中,您期望该方法将调用;在一个 UT 中,您预计方法 x 将调用 3 次,但该方法在测试中被调用两次 + 在其他测试中被调用一次(测试应该失败,但不会......)

因此,最重要的是,您永远不应该使用全局模拟,除非该全局模拟仅用于防止空指针(您没有设置行为..)