You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:37:49