如何使用 google 测试对 gRPC 异步 C++ 客户端函数进行单元测试

How to unit test gRPC asynchronous C++ client functions with google test

我正在尝试使用 google 测试为我的 C++ gRPC 客户端编写单元测试。我同时使用同步和异步 rpc,但我不知道如何使用异步 rpc 的模拟版本。

在我的 .proto 文件中我有:

rpc foo(EmptyMessage) returns (FooReply) {}

由此 protoc 生成了具有同步和异步调用的模拟存根:

  MOCK_METHOD3(foo, ::grpc::Status(::grpc::ClientContext* context, const ::EmptyMessage& request, ::FooReply* response));
  MOCK_METHOD3(AsyncfooRaw, ::grpc::ClientAsyncResponseReaderInterface< ::FooReply>*(::grpc::ClientContext* context, const ::EmptyMessage& request, ::grpc::CompletionQueue* cq));

我可以成功模拟同步调用:

EXPECT_CALL(mockStub, foo).Times (1).WillOnce ([] (grpc::ClientContext *, const ::EmptyMessage &, ::FooReply *repl) {
        // I can set desired values to 'repl' here
        return grpc::Status::OK;
    });

问题:如何使用模拟的异步 foo() rpc?

我试过例如:

EXPECT_CALL(mockStub, AsyncfooRaw).Times (1).WillOnce ([] (::grpc::ClientContext* context, const ::EmptyMessage& request, ::grpc::CompletionQueue* cq)
                                                                           -> grpc_impl::ClientAsyncResponseReaderInterface<::FooReply>* {
   ...

编译,但我得到:

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: AsyncfooRaw

据我了解,这意味着 gmock 找不到我尝试提供的 AsyncfooRaw 的处理程序。

不幸的是,gRPC 不提供为异步创建模拟的方法 API。当异步 API 首次开发时,有一些历史限制使得这不可行,因此,API 并不是真正设计来支持这个。

我们可能希望为新的 callback-based API 提供支持,它旨在取代异步 API。请随时为此提交功能请求。但是,这需要进行一些调查,我不确定我们能多快完成。

在此期间,最好的解决方法是创建服务器实现并在其中添加模拟,而不是直接模拟客户端 API。