使用Google模拟,如何指定EXPECT_CALL的返回值是N次,然后是另一个值N + 1?
我可以通过测试的唯一方法是手动指定每个迭代,例如
EXPECT_CALL(mock, Read(address)).Times(5)
.WillOnce(Return(0))
.WillOnce(Return(0))
.WillOnce(Return(0))
.WillOnce(Return(0))
.WillOnce(Return(1));
测试说明
被测代码使用状态字来确定是否应退出读取数据的循环。 EXPECT_CALL应该设置一个预期,以使模拟方法Read()返回N次为1,并且在第N个周期返回0以指示没有更多数据。
不幸的是,所讨论的代码在单独的机器上,但这是一个典型示例。
const unsigned int statusAddress = 0;
const unsigned int dataAddress = 1;
const unsigned int maxData = 8;
unsigned int dataBuffer[maxData] = {0};
int readIndex = 0;
// Check if data is available (read returns 1).
unsigned int dataIsAvailable = Read(statusAddress);
// Keep reading data until no more is available or the buffer is full.
while ((dataIsAvailable == 1) && (readIndex < maxData))
{
// Read data word.
dataBuffer[readIndex++] = Read(dataAddress);
// Read status to determine if more data is available.
dataIsAvailable = Read(statusAddress);
}
Read方法被模拟。
如果我按顺序添加期望,则使用后者EXPECT_CALL(我假设WillOnce在Google代码中会覆盖WillRepeatedly)。显然我误解了如何订购多个EXPECT_CALL。
EXPECT_CALL(mock, Read(address)).Times(4).WillRepeatedly(Return(1));
EXPECT_CALL(mock, Read(address)).Times(1).WillOnce(Return(0));
Expected: to be called 4 times
Actual: never called - unsatisfied and active
因为没有方法...
WillN(Return(1), 4)
...我认为,对于更复杂和/或更长时间的数据序列,构造EXPECT_CALL的方法不太固定?
答案 0 :(得分:0)
有一个简单的解决方案可以解决您的问题。在您的期望之前创建一个InSequence实例。这将确保以相同的顺序调用书面期望。
InSequence s;
EXPECT_CALL(mock, Read(address)).Times(4).WillRepeatedly(Return(1));
EXPECT_CALL(mock, Read(address)).Times(1).WillOnce(Return(0));
其他信息:click
答案 1 :(得分:-1)
您可能想研究这种测试类型的Delegating Calls to Fake模式。
我认为,如果我需要实施一套处理读取各种数据流的测试,我可能会编写一个混合的Mock / Fake类,该类允许我控制要读取的实际流。例如:
// Example reader class to be tested
class Reader
{
public:
static const unsigned int statusAddress = 0;
static const unsigned int dataAddress = 1;
static const unsigned int maxData = 8;
// Returns data sequence that was read
vector<unsigned int> ReadFromDevice()
{
// Stream-reading code from your example goes here
}
virtual unsigned int Read(unsigned int address)
{
// Read from address code here
}
};
// Mock reader class with some faking ability
class MockReader : public Reader
{
public:
// Set up normal mock definition
MOCK_METHOD1(Read, unsigned int(unsigned int address));
// Optionally enable use of delegation to fake method
void EnableFakeReader()
{
ON_CALL(*this, Read(_))
.WillByDefault(Invoke(this, &MockReader::FakeRead));
}
// Set up a fake data sequence to be returned by Read()
void SetFakeData(const vector<unsigned int> &data)
{
m_fakeData = data;
m_fakeDataIndex = 0;
EnableFakeReader();
}
// Read from fake data sequence
unsigned int FakeRead(unsigned int address)
{
if (address == statusAddress)
return m_fakeDataIndex < m_fakeData.size() ? 1 : 0;
if (address == dataAddress)
if (m_fakeDataIndex < m_fakeData.size())
return m_fakeData[m_fakeDataIndex++];
return 0;
}
vector<unsigned int> m_fakeData;
size_t m_fakeDataIndex = 0;
};
TEST(ReaderTests, Test1)
{
// Set up a fake data sequence to be read
vector<unsigned int> testData ={ 1,2,3,4,5,6,7,8 };
MockReader mock;
mock.SetFakeData(testData);
// Set any desired expectations about mocked functions
EXPECT_CALL(mock, Read(Reader::statusAddress)).Times(9);
EXPECT_CALL(mock, Read(Reader::dataAddress)).Times(8);
// Data read should be the same as the test data
EXPECT_EQ(testData, mock.ReadFromDevice());
}
请注意,此示例未遵循上面链接的Google Mock食谱模式。完整的食谱模式将使您创建一个FakeReader
类和一个MockReader
。 MockReader
将拥有并委托给FakeReader
类的私有实例。
您还可以考虑将假货放入灯具类。