使用gmock模拟gRPC双向流服务端返回预设Reply消息的方法咨询
gRPC双向流服务gmock模拟实现方案
1. 定义Mock服务类
首先继承gRPC生成的服务基类,将目标RPC方法声明为mock方法:
#include <gmock/gmock.h> // 替换为你自己生成的proto头文件名 #include "greeter.grpc.pb.h" using grpc::ServerContext; using grpc::Status; using grpc::ServerReaderWriter; class MockGreeterService : public Greeter::Service { public: MOCK_METHOD(Status, StreamRequestAndReply, (ServerContext*, ServerReaderWriter<Reply, Request>*), (override)); };
2. 模拟预设回复逻辑
你计划用testing::Invoke的思路是可行的,gmock的Invoke动作会将mock方法接收到的所有参数透传给自定义的处理函数/ lambda,你可以直接在lambda中拿到ServerReaderWriter指针,调用Write方法写入预设的回复:
TEST(GrpcClientTest, ReceivePresetReplyTest) { MockGreeterService mock_service; // 此处省略gRPC测试服务启动、客户端连接绑定的通用逻辑 // 设置mock动作,匹配到RPC调用时写入预设消息 EXPECT_CALL(mock_service, StreamRequestAndReply) .WillOnce(testing::Invoke([](ServerContext* ctx, ServerReaderWriter<Reply, Request>* stream) { // 写入3条有效消息 for (int i = 0; i < 3; ++i) { Reply normal_rep; normal_rep.set_msg("valid message " + std::to_string(i)); normal_rep.set_is_eof(false); stream->Write(normal_rep); } // 写入带EOF标记的第四条消息 Reply eof_rep; eof_rep.set_msg("stream end"); eof_rep.set_is_eof(true); stream->Write(eof_rep); // 若需要同步处理客户端发送的请求,可在此处添加Read逻辑 // Request req; // while(stream->Read(&req)) { /* 处理客户端请求 */ } return Status::OK; })); // 此处执行客户端调用逻辑,验证客户端收到的消息是否符合预期 }
3. 常见扩展需求说明
- 如果你需要在测试用例中单独控制消息写入时机,不需要在Invoke里一次性写完,可以用
testing::SaveArg<1>(&pre_declared_stream_ptr)将stream指针保存到测试用例的局部变量中,后续可在任意时机调用指针的Write方法发送消息 - 如果需要模拟异常场景,直接返回非OK的
Status,或者中断写入即可 - 所有正常服务端能调用的
ServerReaderWriter方法,在mock的处理逻辑里都可以直接调用,写法和真实服务端实现完全一致
内容的提问来源于stack exchange,提问作者Tinyden
相关产品推荐
相关产品推荐

