In this lesson, you will learn how to verify your gRPC service communication contracts by leveraging the Microsoft.AspNetCore.Mvc.Testing infrastructure to host your service in-memory.
The gRPC Testing Philosophy
When testing gRPC, we move beyond simple unit tests. Because gRPC relies on strict Protobuf contracts, we need to ensure our service implementation correctly responds to real gRPC requests. Rather than mocking the underlying transport, we use the WebApplicationFactory<TEntryPoint> to spin up an in-memory server, allowing us to send actual gRPC calls through the middleware pipeline.
Implementing the Integration Test
To verify the contract, you act as the client. You create a channel that points to the in-memory HttpClient provided by the factory, then use the generated gRPC client stub to perform your assertions.
public class GreeterServiceTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
public GreeterServiceTests(WebApplicationFactory<Program> factory) => _factory = factory;
[Fact]
public async Task SayHello_ReturnsExpectedReply()
{
// Arrange: Create a channel that uses the server's HttpClient
var client = new Greeter.GreeterClient(_factory.CreateGrpcChannel());
// Act: Invoke the service method
var response = await client.SayHelloAsync(new HelloRequest { Name = "World" });
// Assert: Verify the contract matches expectations
Assert.Equal("Hello World", response.Message);
}
}
Why Use CreateGrpcChannel?
The CreateGrpcChannel() helper (found in Microsoft.AspNetCore.TestHost) is critical. It configures the GrpcChannel to route traffic directly to the HttpMessageHandler inside your test server rather than over the network. This ensures your tests remain fast, self-contained, and isolated from external port conflicts.
By testing through the client stub, you aren't just testing the logic inside your service class; you are validating the entire serialization and deserialization flow, ensuring that your Protobuf definitions and service implementation are perfectly synchronized. If you change a field name in your .proto file but forget to update the implementation, these tests will fail during the request-response handshake, alerting you to the broken contract immediately.
Key Takeaway: Use WebApplicationFactory with CreateGrpcChannel to perform end-to-end contract verification against an in-memory test server, ensuring your gRPC service honors its Protobuf definitions.