mardi 27 août 2019

Spoofing grpc UnaryHandler for unit testing gRPC in Go

I'm working on improving coverage for my Go gRPC server but I have run into trouble writing a test for the server's interceptor function because I'm unable to meaningfully satisfy the UnaryHandler type.

I have a function Interceptor with the following signature:

Interceptor func(
  ctx context.Context,
  req interface{},
  info *grpc.UnaryServerInfo,
  handler grpc.UnaryHandler, // <- my issue comes from here
) (interface{}, error)

I assumed that any gRPC method would satisfy the signature of UnaryHandler:

type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error)

So I tried passing in a method with this signature:

GetToken(ctx context.Context, req *AuthData) (*Token, error)

I imagined this would work, since this is what the Interceptor is actually doing (forwarding that RPC), but for some reason Go complains:

cannot use authService.GetToken (type func(context.Context, *AuthData) (*Token, error)) as type grpc.UnaryHandler in argument to Interceptor

I went ahead and wrote a dummy function that correctly satisfies:

func genericHandler(ctx context.Context, req interface{}) (interface{}, error) {
    return req, nil
}

which is fine since I don't particularly need to run any specific method when testing the interceptor. However I am curious as to why the actual method doesn't satisfy the constraints because (according to my understanding) it is being passed to the Interceptor function under hood whenever I call that RPC in the wild.

The most likely explanation is that the grpc UnaryHandler doesn't do what I'm thinking it does, but then what does it do?

Aucun commentaire:

Enregistrer un commentaire