c++ Google Mock -如何使用EXPECT_CALL返回不同的值以退出循环

3duebb1j  于 11个月前  发布在  Go
关注(0)|答案(2)|浏览(330)

使用google mock,我如何指定一个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代码中覆盖了WillRepeatly)。

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?

pftdvrlh

pftdvrlh1#

有一个简单的方法可以解决你的问题。在你的期望之前创建一个InSequence的示例。这将保证以相同的顺序调用编写的期望。

InSequence s;
EXPECT_CALL(mock, Read(address)).Times(4).WillRepeatedly(Return(1));
EXPECT_CALL(mock, Read(address)).Times(1).WillOnce(Return(0));

字符串
更多信息:点击

p5fdfcr1

p5fdfcr12#

对于这种类型的测试,您可能需要研究委托调用到假模式。
我想如果我需要实现一套处理阅读各种数据流的测试,我可能会编写一个混合的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 cookbook模式。完整的cookbook模式将让您创建一个FakeReader类以及一个MockReaderMockReader将拥有并委托给FakeReader类的私有示例。
您还可以考虑将fake放入fixture类中。

相关问题