我正在嘲笑一个用于读取串行数据的低级接口。该接口具有公共函数,用于从其内部缓冲区读取字节。我想模拟这个接口,所以我可以返回一个字节序列,并且对于返回的每个字节也返回值true
。一旦超出要读取的字节数,该函数必须返回false
我现在正在做的事情如下:
struct IUart
{
virtual bool Read(uint8_t& value) = 0;
//... other functions
};
struct MockUart: IUart
{
MOCK_METHOD1(Read, bool(uint8_t&));
//... other functions
};
struct TestMyTest: ::testing::Test
{
/* Setting up test fixture */
};
TEST_F(TestMyTest, TestMyMockedInterface)
{
MockUart uartMock;
EXPECT_CALL(uartMock, Read(::testing::_))
.WillOnce(::testing::DoAll(::testing::SetArgReferee<0>(10), ::testing::Return(true)))
.WillOnce(::testing::DoAll(::testing::SetArgReferee<0>(11), ::testing::Return(true)))
.WillOnce(::testing::DoAll(::testing::SetArgReferee<0>(12), ::testing::Return(true)))
.WillOnce(::testing::Return(false));
//... etc
}
还有其他方法可以促进这一点吗?是否有一些::testing::WithNextValueFromArray
选项可供选择?
答案 0 :(得分:1)
没有什么比你所描述的更好,而且#34;开箱即用&#34;在谷歌模拟,但你可以编写自己的行动来实现这一目标。但是,有几种方法可以解决这个问题:
编写一个几乎完全符合您所描述的操作:
{{2然后按如下方式使用它:ACTION_TEMPLATE(SetArgWithNextValueFromArray,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(results))
{
::testing::get<k>(args) = results->front();
results->erase(results->begin());
}
此操作具有可以与其他测试重用的优点,但它仍然有些冗长。
< h1>选项2编写一个从UART成功模拟阅读的操作:
TEST_F(TestMyTest, TestMyMockedInterface)
{
MockUart uartMock;
std::vector<uint8_t> results = { 10, 11, 12 };
EXPECT_CALL(uartMock, Read(::testing::_))
.WillOnce(::testing::DoAll(SetArgWithNextValueFromArray<0>(&results),::testing::Return(true)))
.WillOnce(::testing::DoAll(SetArgWithNextValueFromArray<0>(&results),::testing::Return(true)))
.WillOnce(::testing::DoAll(SetArgWithNextValueFromArray<0>(&results),::testing::Return(true)))
.WillOnce(::testing::Return(false));
}
然后按如下方式使用它:
ACTION_P(ReadSuccessfully, results)
{
arg0 = results->front();
results->erase(results->begin());
return true;
}
< p>此操作的可重用性较低,但不太详细。 编写一个模拟UART读取的操作:
TEST_F(TestMyTest, TestMyMockedInterface)
{
MockUart uartMock;
std::vector<uint8_t> results = { 10, 11, 12 };
EXPECT_CALL(uartMock, Read(::testing::_))
.WillOnce(ReadSuccessfully(&results))
.WillOnce(ReadSuccessfully(&results))
.WillOnce(ReadSuccessfully(&results))
.WillOnce(::testing::Return(false));
}
然后按如下方式使用它:
ACTION_P(FakeRead, results)
{
if (results->empty())
{
return false;
}
arg0 = results->front();
results->erase(results->begin());
return true;
}
此操作也不是非常可重用,但是最不详细。该操作具有TEST_F(TestMyTest, TestMyMockedInterface)
{
MockUart uartMock;
std::vector<uint8_t> results = { 10, 11, 12 };
EXPECT_CALL(uartMock, Read(::testing::_)).WillRepeatedly(FakeRead(&results));
}
的完整虚假实现,这对于您的某些测试非常有用。另一方面,一个完整的假实现本身可能是错误的,这可能会对您的测试产生负面影响。
可能还有其他选择,但这些应该可以提供足够的实例来说明。