Link to NuGet: https://www.nuget.org/packages/WireMock.Grpc.Protobuf
Statically typed gRPC mocking for WireMock.Net using generated Google.Protobuf contracts.
Request.Create()
.WithBodyAsGoogleProtobuf(new HelloRequest { Name = "Stepan" });
Response.Create()
.WithBodyAsGoogleProtobuf(
new HelloReply { Message = "Hello, Stepan!" });No ProtoDefinition, message type strings, JSON conversion, or manually constructed binary payloads.
The standard WireMock.Net protobuf integration requires loading .proto definitions and referring to protobuf message types separately from your generated C# contracts.
This package uses the generated IMessage<T> types you already have to write less configuration and do no duplicated schema setup:
- compile-time type safety;
- native
Google.Protobufserialization; - exact-message and predicate request matching;
When a contract changes, outdated mocks stop compiling instead of failing at runtime.
dotnet add package WireMock.Grpc.ProtobufThe package targets .NET Standard 2.0 and .NET 8.
Assuming you have some greet.proto file that generates HelloRequest, HelloReply, and Greeter.GreeterClient for instance:
syntax = "proto3";
option csharp_namespace = "Greeting.Contracts";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}And assuming you also have the required packages added with protobuf compilation settings to your test project:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="WireMock.Net" Version="2.13.0" />
<PackageReference Include="WireMock.Grpc.Protobuf" Version="1.0.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.80.0" />
<PackageReference Include="Grpc.Core" Version="2.46.6"/>
<PackageReference Include="Grpc.Tools" Version="2.82.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Protobuf Include=".\test.proto" GrpcServices="Client" />
</ItemGroup>
</Project>Start WireMock.Net with HTTP/2 enabled and configure the expected request and response using the WithBodyAsGoogleProtobuf extension methods:
using Greeting.Contracts;
using Grpc.Net.Client;
using WireMock.Net.Google.Protobuf.Request;
using WireMock.Net.Google.Protobuf.Response;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
using var server = WireMockServer.Start(
new WireMockServerSettings
{
UseHttp2 = true
});
var request = new HelloRequest
{
Name = "Stepan"
};
var expectedResponse = new HelloReply
{
Message = "Hello, Stepan!"
};
server
.Given(
Request.Create()
.UsingPost()
.WithHttpVersion("2")
.WithPath("/greet.Greeter/SayHello")
.WithBodyAsGoogleProtobuf(request))
.RespondWith(
Response.Create()
.WithHeader("Content-Type", "application/grpc")
.WithTrailingHeader("grpc-status", "0")
.WithBodyAsGoogleProtobuf(expectedResponse));
using var channel = GrpcChannel.ForAddress(server.Url!);
var client = new Greeter.GreeterClient(channel);
var actualResponse = await client.SayHelloAsync(request);
Assert.Equal(expectedResponse, actualResponse);Match only the fields relevant to your test:
Request.Create()
.WithBodyAsGoogleProtobuf<HelloRequest>(
request =>
request.Name.StartsWith("Step") &&
request.Name.Length >= 5);This keeps request matching strongly typed without comparing the entire protobuf message.
Do not call WithTransformer() after WithBodyAsGoogleProtobuf(). The response is already a binary gRPC frame, and text transformation may corrupt it.
WireMock.Net must also run with HTTP/2 enabled:
new WireMockServerSettings
{
UseHttp2 = true
};Distributed under the MIT License.