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

GTest/GMock:为输入输出指针参数设值的方法及类型错误解决

解决Google Mock中unsigned char*输入输出参数的赋值问题

你遇到的问题本质是SetArgumentPointee<0>的使用场景不对——它是用来给指针指向的单个基础类型值赋值的,但你的场景是把Data*强转成unsigned char*传入,需要给整块结构体内存填充数据,直接用它会因为类型不匹配(试图将Data结构体转成unsigned char)报错。下面是两种可行的解决方法:

方法一:自定义ACTION做内存拷贝(推荐)

因为要给unsigned char*指向的内存(实际对应Data结构体)填充整块数据,自定义一个ACTION来完成内存复制是最稳妥的方式:

首先定义ACTION模板:

ACTION_TEMPLATE(SetArgNToStruct,
                HAS_1_TEMPLATE_PARAMS(int, N),
                AND_1_VALUE_PARAMS(data)) {
  memcpy(arg[N], &data, sizeof(data));
}

然后在Mock调用时使用:

// 构造要填充的Data实例
Data target_data;
target_data.id = 1001;
target_data.status = 0x01;
// 匹配write_data的调用,根据mode设置对应行为
EXPECT_CALL(mock_tcp, write_data(_, Eq(MODE_PROCESS)))
    .WillOnce(SetArgNToStruct<0>(target_data));

方法二:强制类型转换配合SetArgumentPointee

如果能确保unsigned char*指向的内存足够容纳Data结构体,可以直接把参数转成Data*后赋值:

Data target_data;
target_data.id = 2002;
target_data.status = 0x02;

EXPECT_CALL(mock_tcp, write_data(_, Eq(MODE_QUERY)))
    .WillOnce(DoAll(
        // 将arg[0]强制转为Data*,然后给指向的结构体赋值
        SetArgumentPointee<0>(*reinterpret_cast<Data*>(arg[0])),
        // 如果write_data有返回值,这里添加Return语句
        Return(0)
    ));

注意:这种方法要保证arg[0]指向的内存大小≥sizeof(Data),避免内存越界。

额外注意事项

  • 确认write_data的第一个参数是输入输出型:即TestedClass在调用时已经分配好足够的内存(Data结构体大小),Mock只需要填充数据即可
  • 若需根据不同mode执行不同操作,在EXPECT_CALL里精准匹配mode参数(比如Eq(MODE_X)),分别设置对应的填充数据和行为

内容的提问来源于stack exchange,提问作者LPo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:35:11