我经常遇到这样的问题,即在测试的“有趣”部分开始之前,模拟对象需要进入某种状态。
例如,假设我要测试以下类:
struct ToTest
{
virtual void onEnable();
virtual void doAction();
};
因此,我创建了以下模拟类:
struct Mock : ToTest
{
MOCK_METHOD0(onEnable, void());
MOCK_METHOD0(doAction, void());
};
第一个测试是 onEnable
当系统使用 ToTest
时被调用启用对象:
TEST(SomeTest, OnEnable)
{
Mock mock;
// register mock somehow
// interesting part of the test
EXPECT_CALL(mock, onEnable());
EnableSystem();
}
到目前为止,还不错。第二个测试是 doAction
在系统执行操作时调用并启用。因此,应该在测试的有趣部分开始之前启用系统:
TEST(SomeTest, DoActionWhenEnabled)
{
Mock mock;
// register mock somehow
// initialize system
EnableSystem();
// interesting part of the test
EXPECT_CALL(mock, doAction());
DoSomeAction();
}
这有效,但会发出一个恼人的警告,提示对 onEnable
的无趣调用.这个问题似乎有两个常见的修复方法:
- 使用
NiceMock<Mock>
禁止所有此类警告;和 - 添加
EXPECT_CALL(mock, onEnable())
声明。
我不想使用第一种方法,因为可能会有其他不应该发生的无趣调用。我也不喜欢第二种方法,因为我已经(在第一个测试中)测试了 onEnable
当系统启用时被调用;因此,我不想在启用系统上运行的所有测试中重复这种期望。
我希望能够做到的是,到某个点为止的所有模拟调用都应该被完全忽略。在此示例中,我希望仅从“测试的有趣部分”评论开始检查期望。
有没有办法使用 Google Mock 来完成此操作?
最佳答案
烦人的是必要的函数都在那里:gmock/gmock-spec-builders.h
定义了Mock::AllowUninterestingCalls
等来控制警告的产生对于特定的模拟对象。使用这些函数,应该可以暂时禁用有关无趣调用的警告。
然而,问题在于这些函数是私有(private)的。好消息是 Mock
类有一些可以被滥用的模板 friend (例如,NiceMock
)。所以我创建了以下解决方法:
namespace testing
{
// HACK: NiceMock<> is a friend of Mock so we specialize it here to a type that
// is never used to be able to temporarily make a mock nice. If this feature
// would just be supported, we wouldn't need this hack...
template<>
struct NiceMock<void>
{
static void allow(const void* mock)
{
Mock::AllowUninterestingCalls(mock);
}
static void warn(const void* mock)
{
Mock::WarnUninterestingCalls(mock);
}
static void fail(const void* mock)
{
Mock::FailUninterestingCalls(mock);
}
};
typedef NiceMock<void> UninterestingCalls;
}
这让我可以通过 UninterestingCalls
typedef 访问私有(private)函数。
关于c++ - 在设置阶段忽略模拟调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22745349/