GoogleMock模拟串口读取接口:输出参数返回序列字节与状态
我来给你完善这个串口Mock的实现,刚好能满足你要的「按预设序列返回字节、耗尽后返回false」的需求,用Google Mock来实现非常顺手:
首先先补全接口和Mock的完整代码,注意给基类加上虚析构(这是多态类的必备操作,避免内存泄漏):
#include <gmock/gmock.h> #include <queue> #include <cstdint> #include <vector> struct IUart { virtual bool Read(uint8_t& value) = 0; // 其他虚函数可以放在这里... virtual ~IUart() = default; // 必须的虚析构 }; struct MockUart : IUart { MOCK_METHOD1(Read, bool(uint8_t& value)); // 用来设置要返回的字节序列 void SetReadBytes(const std::vector<uint8_t>& bytes) { read_queue = std::queue<uint8_t>(bytes.begin(), bytes.end()); } private: std::queue<uint8_t> read_queue; // 核心逻辑:从队列取字节,返回是否有数据可读 bool DoRead(uint8_t& value) { if (read_queue.empty()) { return false; } value = read_queue.front(); read_queue.pop(); return true; } public: MockUart() { // 把Read方法的默认行为绑定到DoRead ON_CALL(*this, Read).WillByDefault(::testing::Invoke(this, &MockUart::DoRead)); } };
怎么用这个Mock?
很简单,先调用SetReadBytes传入你想要返回的字节序列,之后每次调用Read就会自动按顺序返回字节,直到序列耗尽:
TEST(UartReaderTest, ReturnsBytesInOrder) { MockUart mock_uart; // 设置要返回的字节:0x10, 0x20, 0x30 mock_uart.SetReadBytes({0x10, 0x20, 0x30}); uint8_t received_val; // 前三次调用成功拿到字节 EXPECT_TRUE(mock_uart.Read(received_val)); EXPECT_EQ(received_val, 0x10); EXPECT_TRUE(mock_uart.Read(received_val)); EXPECT_EQ(received_val, 0x20); EXPECT_TRUE(mock_uart.Read(received_val)); EXPECT_EQ(received_val, 0x30); // 第四次调用没有字节了,返回false EXPECT_FALSE(mock_uart.Read(received_val)); }
额外技巧:灵活覆盖默认行为
如果需要在某些特定调用时返回自定义结果(比如模拟中途出错),可以用EXPECT_CALL临时覆盖默认逻辑,之后的调用会回到队列的默认行为:
TEST(UartReaderTest, OverrideBehaviorTemporarily) { MockUart mock_uart; mock_uart.SetReadBytes({0x01, 0x02}); uint8_t val; // 第一次调用强制返回false,忽略队列里的字节 EXPECT_CALL(mock_uart, Read(testing::_)).WillOnce(testing::Return(false)); EXPECT_FALSE(mock_uart.Read(val)); // 之后的调用继续从队列取数据 EXPECT_TRUE(mock_uart.Read(val)); EXPECT_EQ(val, 0x01); }
这个实现既简洁又灵活,完全符合你要的需求~
内容的提问来源于stack exchange,提问作者Daan Timmer
相关产品推荐
相关产品推荐

