【发布时间】:2020-01-01 00:34:50
【问题描述】:
我正在努力提高我的 Go gRPC 服务器的覆盖率,但我在为服务器的拦截器函数编写测试时遇到了麻烦,因为我无法有意义地满足 UnaryHandler 类型。
我有一个函数Interceptor,签名如下:
Interceptor func(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler, // <- my issue comes from here
) (interface{}, error)
我假设任何 gRPC 方法都会满足 UnaryHandler 的签名:
type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error)
所以我尝试传入一个带有这个签名的方法:
GetToken(ctx context.Context, req *AuthData) (*Token, error)
我认为这会起作用,因为这就是拦截器实际上正在做的事情(转发该 RPC),但出于某种原因,Go 抱怨:
不能在 Interceptor 的参数中使用 authService.GetToken (type func(context.Context, *AuthData) (*Token, error)) 作为类型 grpc.UnaryHandler
我继续写了一个正确满足的虚拟函数:
func genericHandler(ctx context.Context, req interface{}) (interface{}, error) {
return req, nil
}
这很好,因为我在测试拦截器时并不特别需要运行任何特定的方法。但是我很好奇为什么实际方法不满足约束,因为(根据我的理解)每当我在野外调用该 RPC 时,它都会被传递给幕后的拦截器函数。
最可能的解释是 grpc UnaryHandler 没有做我认为的那样,但是它做了什么?
【问题讨论】:
-
难道不是因为它需要
interface{}并且您正在传递并返回一个引用吗?也许它会匹配*interface{}?也就是说,在实现方面,它应该匹配一个指针,因为接口假定一个指针,但我不确定语法。