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
相关产品推荐
相关产品推荐

