我第一次尝试使用GMock(谷歌的模拟框架)。我有以下课程:
class LocalCache
{
public:
virtual time_t GetCurrentTime() = 0;
virtual int AddEntry(const std::string key, std::string& value);
virtual int GetEntry(const std::string key, std::string& value);
};
GetEntry方法调用GetCurrentTime调用。我想模拟GetCurrentTime方法,以便我可以在我的测试中推进时钟来测试GetEntry调用中发生的条目的老化(请不要问我老化的原因是什么作为GetEntry调用的一部分完成...那是另一个讨论:()。这是我的模拟课程:
class MockLocalCache : public LocalCache
{
public:
using LocalCache::GetCurrentTime;
MOCK_METHOD0(GetCurrentTime, time_t());
MockLocalCache()
: mCurrentTime(0)
{
}
void EnableFakeTime()
{
ON_CALL(*this, GetCurrentTime()).WillByDefault(Return(mCurrentTime));
}
void SetTime(time_t now) { mCurrentTime = now; }
private:
time_t mCurrentTime;
};
TEST(MockTest, TimeTest)
{
MockLocalCache mockCache;
mockCache.EnableFakeTime();
std::string key("mykey");
std::string value("My Value");
EXPECT_TRUE(mockCache.AddEntry(key, value));
mockCache.SetTime(10); // advance 10 seconds
std::string expected;
EXPECT_TRUE(mockCache.GetEntry(key, expected));
}
当我进行测试时,我期待“当前时间”。我的模拟GetCurrentTime函数返回的值。但是,我得到以下错误输出:
GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
..../test_local_cache.cpp:62:
Function call: GetCurrentTime()
Returns: 0
Stack trace:
如果有人能让我知道我做错了什么以及如何解决它,我将不胜感激。提前致谢。
答案 0 :(得分:4)
解决问题的方法是以更简单的方式解决问题。只需使用您希望调用模拟函数的EXPECT_CALL
:
class MockLocalCache : public LocalCache
{
public:
MOCK_METHOD0(GetCurrentTime, time_t());
};
TEST(MockTest, TimeTest)
{
MockLocalCache mockCache;
std::string key("mykey");
std::string value("My Value");
EXPECT_TRUE(mockCache.AddEntry(key, value));
EXPECT_CALL(mockCache, GetCurrentTime()).WillOnce(Return(10)); // advance 10 seconds
std::string expected;
EXPECT_TRUE(mockCache.GetEntry(key, expected));
}
只是回答为什么你的例子不起作用 - 通过这个调用,你的成员变量的当前值被存储 - 以后更改它没有任何效果:
ON_CALL(*this, GetCurrentTime()).WillByDefault(Return(mCurrentTime));
在JavaDocs Switch Satement中查看Return
和Return(ByRef
...
可能 - 我没有检查这个,调用set成员值,在调用之前设置这个默认值也可以 - 但正如我所说的 - 对于你的情况应该使用EXPECT_CALL:
mockCache.SetTime(10); // advance 10 seconds
mockCache.EnableFakeTime();
答案 1 :(得分:0)
仅作记录(以后的人们会像我一样找到这个问题),而PiotrNycz's answer是您可以做到的最佳选择(将测试值直接保存在测试中)–在某些情况下,确实是从字段或变量返回“实时”返回值所必需。
适当的文档为here;特别是:
Return(field)
不起作用(定义操作后会复制该字段的当前值)Return(ByRef(field))
也不起作用(它与上述功能完全相同,这与您的预期相反)ReturnRef(field)
无法编译(因为返回类型不是引用)ReturnPointee(&field)
起作用(它返回实际调用该方法时的值)当然,您必须确保每次调用该方法时pointee仍然有效,因为现在直接使用它而不是制作副本。