I am using the packages Grpc.Core
and ProtoBuf.Grpc
because I want to use both: Code-First gRPC with gRPC ClientFactory.
Now I have an interface of form Task<Response> MyMethod(Request request, CallContext context)
with CallContext
coming from ProtoBuf.Grpc
.
In the implementation of the interface I get the authorized (calling) user like this:
var user = httpContext.User.Claims.Where(x => x.Type == JwtRegisteredClaimNames.Name).FirstOrDefault();
Now I want to unit test my implementation of MyMethod
but I do not know how to create the correct context for CallContext
with a test user.
How can I test my implementation MyMethod
with a predefined user in the CallContext
?
Edit:
It seems possible to create and pass an instance of CallContext
by calling the constructor
public CallContext(object server, ServerCallContext context)
I can create the ServerCallContext
object via TestServerCallContext.Create()
, see here.
However I do not know what to pass for object server
. Does anyone have an example for me?
CodePudding user response:
For unit testing gRPC
with authentication and user context the following approach was my solution:
public static ProtoBuf.Grpc.CallContext TestCallContext(Guid user)
{
var serverCallContext = TestServerCallContext.Create(
method: nameof(IGrpcGreetingService.Greeting)
, host: "localhost"
, deadline: DateTime.Now.AddMinutes(30)
, requestHeaders: new Metadata()
, cancellationToken: CancellationToken.None
, peer: "10.0.0.25:5001"
, authContext: null
, contextPropagationToken: null
, writeHeadersFunc: (metadata) => Task.CompletedTask
, writeOptionsGetter: () => new WriteOptions()
, writeOptionsSetter: (writeOptions) => { }
);
var claims = new[] {
new Claim(JwtRegisteredClaimNames.Sub, "some subject"),
new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
new Claim(JwtRegisteredClaimNames.Name, user.ToString())
};
var claimsIdentity = new ClaimsIdentity(claims);
var httpContext = new DefaultHttpContext();
httpContext.User = new ClaimsPrincipal(claimsIdentity);
serverCallContext.UserState["__HttpContext"] = httpContext;
return new ProtoBuf.Grpc.CallContext("", serverCallContext);
}
With arguments for TestServerCallContext.Create
from here.
Maybe this can help somebody else save some hours or days :)