grpc multiple request/response in single mock #652

Closed
opened 2025-12-29 15:29:45 +01:00 by adam · 7 comments
Owner

Originally created by @GomesNayagam on GitHub (Dec 19, 2024).

Originally assigned to: @StefH on GitHub.

Ask question related to the repo, e.g:

How to to achieve feeding multiple request and response in single server url setup
e.g

             server
                .Given(
                    Request
                        .Create()
                        .UsingPost()
                        .WithHttpVersion("2")
                        .WithPath("/Policy.PolicyService2/**")
                )
                .WithProtoDefinition(id)
                .RespondWith(
                    Response
                        .Create()
                        .WithHeader("Content-Type", "application/grpc")
                        .WithTrailingHeader("grpc-status", "0")
                        .WithBodyAsProtoBuf(
                            protoDefinition,
                            "Policy.GetVersion2Response",
                            new { Version = "Dev1" }
                        )
                        .WithBodyAsProtoBuf(
                            protoDefinition,
                            "Policy.GetVersionResponse",
                            new { Version = "Dev2" }
                        )
                        .WithTransformer()
                );

            // Act
            var channel = GrpcChannel.ForAddress(server.Url!);

            var client = new PolicyService2.PolicyService2Client(channel);
            Policy.Client cl =
                new() { ClientName = Policy.Client.Types.Clients.Pas, CorrelationId = "12345" };

            var reply = await client.GetVersion2Async(new GetVersion2Request { Client = cl });
            var reply2 = await client.GetVersionAsync(new Policy.GetVersionRequest { Client = cl });

            // Assert
            reply.Version.Should().Be("Dev1"); --> this is and
            reply2.Version.Should().Be("Dev2"); -> return same value

sample proto:

syntax = "proto3";

package Policy;

service PolicyService2 {	
    rpc GetVersion (GetVersionRequest) returns (GetVersionResponse);
	rpc GetVersion2 (GetVersion2Request) returns (GetVersion2Response);
}

// REQUEST/RESPONSE DEFINITIONS
message GetVersion2Request {
  Client Client = 1;

}
message GetVersion2Response {
  string Version = 1;
}
message GetVersionRequest {
  Client Client = 1;
}
message GetVersionResponse {
  string Version = 1;
}
Originally created by @GomesNayagam on GitHub (Dec 19, 2024). Originally assigned to: @StefH on GitHub. Ask question related to the repo, e.g: How to to achieve feeding multiple request and response in single server url setup e.g ``` c# server .Given( Request .Create() .UsingPost() .WithHttpVersion("2") .WithPath("/Policy.PolicyService2/**") ) .WithProtoDefinition(id) .RespondWith( Response .Create() .WithHeader("Content-Type", "application/grpc") .WithTrailingHeader("grpc-status", "0") .WithBodyAsProtoBuf( protoDefinition, "Policy.GetVersion2Response", new { Version = "Dev1" } ) .WithBodyAsProtoBuf( protoDefinition, "Policy.GetVersionResponse", new { Version = "Dev2" } ) .WithTransformer() ); // Act var channel = GrpcChannel.ForAddress(server.Url!); var client = new PolicyService2.PolicyService2Client(channel); Policy.Client cl = new() { ClientName = Policy.Client.Types.Clients.Pas, CorrelationId = "12345" }; var reply = await client.GetVersion2Async(new GetVersion2Request { Client = cl }); var reply2 = await client.GetVersionAsync(new Policy.GetVersionRequest { Client = cl }); // Assert reply.Version.Should().Be("Dev1"); --> this is and reply2.Version.Should().Be("Dev2"); -> return same value ``` sample proto: ``` proto syntax = "proto3"; package Policy; service PolicyService2 { rpc GetVersion (GetVersionRequest) returns (GetVersionResponse); rpc GetVersion2 (GetVersion2Request) returns (GetVersion2Response); } // REQUEST/RESPONSE DEFINITIONS message GetVersion2Request { Client Client = 1; } message GetVersion2Response { string Version = 1; } message GetVersionRequest { Client Client = 1; } message GetVersionResponse { string Version = 1; } ```
adam added the question label 2025-12-29 15:29:45 +01:00
adam closed this issue 2025-12-29 15:29:45 +01:00
Author
Owner

@StefH commented on GitHub (Dec 19, 2024):

Defining and using multiple Grpc Protobuf mappings is not different then defining multiple normal mappings.

So in your case you need to define 2 mappings with 2 different request paths and 2 different respones.
So instead of .WithPath("/Policy.PolicyService2/**"), you need:

Mapping 1

.WithPath("/Policy.PolicyService2/GetVersion")

and use response

.WithBodyAsProtoBuf(
  protoDefinition,
  "Policy.GetVersionResponse",
  new { Version = "Dev1" }
)

Mapping 2

.WithPath("/Policy.PolicyService2/GetVersion2")

and use response

.WithBodyAsProtoBuf(
  protoDefinition,
  "Policy.GetVersionResponse2",
  new { Version = "Dev2" }
)
@StefH commented on GitHub (Dec 19, 2024): Defining and using multiple Grpc Protobuf mappings is not different then defining multiple normal mappings. So in your case you need to define 2 mappings with 2 different request paths and 2 different respones. So instead of `.WithPath("/Policy.PolicyService2/**")`, you need: ## Mapping 1 `.WithPath("/Policy.PolicyService2/GetVersion")` and use response ``` c# .WithBodyAsProtoBuf( protoDefinition, "Policy.GetVersionResponse", new { Version = "Dev1" } ) ``` ## Mapping 2 `.WithPath("/Policy.PolicyService2/GetVersion2")` and use response ``` c# .WithBodyAsProtoBuf( protoDefinition, "Policy.GetVersionResponse2", new { Version = "Dev2" } ) ```
Author
Owner

@GomesNayagam commented on GitHub (Dec 20, 2024):

thanks for quick response @StefH and is there any way to use some json file rather declarative way?

@GomesNayagam commented on GitHub (Dec 20, 2024): thanks for quick response @StefH and is there any way to use some json file rather declarative way?
Author
Owner

@StefH commented on GitHub (Dec 20, 2024):

yes this is possible.
However I cannot find an example quickly.
What you can do is run this code in console app and then accesss the /mapings endpoint to retrieve it as json

@StefH commented on GitHub (Dec 20, 2024): yes this is possible. However I cannot find an example quickly. What you can do is run this code in console app and then accesss the /mapings endpoint to retrieve it as json
Author
Owner

@StefH commented on GitHub (Dec 21, 2024):

@GomesNayagam

An example could be:

[
  {
    "Guid": "98fae52e-76df-47d9-876f-2ee32e931000",
    "UpdatedAt": "2024-12-21T07:10:12.6567323Z",
    "Request": {
      "Path": {
        "Matchers": [
          {
            "Name": "WildcardMatcher",
            "Pattern": "/grpc/greet.Greeter/SayHello",
            "IgnoreCase": false
          }
        ]
      },
      "Methods": [
        "POST"
      ],
      "Body": {
        "Matcher": {
          "Name": "ProtoBufMatcher",
          "Pattern": "\r\nsyntax = \"proto3\";\r\n\r\npackage greet;\r\n\r\nservice Greeter {\r\n  rpc SayHello (HelloRequest) returns (HelloReply);\r\n}\r\n\r\nmessage HelloRequest {\r\n  string name = 1;\r\n}\r\n\r\nmessage HelloReply {\r\n  string message = 1;\r\n}\r\n",
          "ContentMatcher": {
            "Name": "JsonPartialWildcardMatcher",
            "Pattern": {
              "name": "*"
            },
            "IgnoreCase": false,
            "Regex": false
          },
          "ProtoBufMessageType": "greet.HelloRequest"
        }
      }
    },
    "Response": {
      "BodyAsJson": {
        "message": "hello {{request.BodyAsJson.name}}"
      },
      "UseTransformer": true,
      "TransformerType": "Handlebars",
      "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert",
      "Headers": {
        "Content-Type": "application/grpc"
      },
      "TrailingHeaders": {
        "grpc-status": "0"
      },
      "ProtoDefinition": "\r\nsyntax = \"proto3\";\r\n\r\npackage greet;\r\n\r\nservice Greeter {\r\n  rpc SayHello (HelloRequest) returns (HelloReply);\r\n}\r\n\r\nmessage HelloRequest {\r\n  string name = 1;\r\n}\r\n\r\nmessage HelloReply {\r\n  string message = 1;\r\n}\r\n",
      "ProtoBufMessageType": "greet.HelloReply"
    }
  },
  {
    "Guid": "98fae52e-76df-47d9-876f-2ee32e931001",
    "UpdatedAt": "2024-12-21T07:10:12.6582715Z",
    "Request": {
      "Path": {
        "Matchers": [
          {
            "Name": "WildcardMatcher",
            "Pattern": "/grpc2/greet.Greeter/SayHello",
            "IgnoreCase": false
          }
        ]
      },
      "Methods": [
        "POST"
      ],
      "Body": {
        "Matcher": {
          "Name": "ProtoBufMatcher",
          "ContentMatcher": {
            "Name": "JsonPartialWildcardMatcher",
            "Pattern": {
              "name": "*"
            },
            "IgnoreCase": false,
            "Regex": false
          },
          "ProtoBufMessageType": "greet.HelloRequest"
        }
      }
    },
    "Response": {
      "BodyAsJson": {
        "message": "hello {{request.BodyAsJson.name}}"
      },
      "UseTransformer": true,
      "TransformerType": "Handlebars",
      "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert",
      "Headers": {
        "Content-Type": "application/grpc"
      },
      "TrailingHeaders": {
        "grpc-status": "0"
      },
      "ProtoBufMessageType": "greet.HelloReply"
    },
    "ProtoDefinition": "\r\nsyntax = \"proto3\";\r\n\r\npackage greet;\r\n\r\nservice Greeter {\r\n  rpc SayHello (HelloRequest) returns (HelloReply);\r\n}\r\n\r\nmessage HelloRequest {\r\n  string name = 1;\r\n}\r\n\r\nmessage HelloReply {\r\n  string message = 1;\r\n}\r\n"
  },
  {
    "Guid": "98fae52e-76df-47d9-876f-2ee32e931002",
    "UpdatedAt": "2024-12-21T07:10:12.6602685Z",
    "Request": {
      "Path": {
        "Matchers": [
          {
            "Name": "WildcardMatcher",
            "Pattern": "/grpc3/greet.Greeter/SayHello",
            "IgnoreCase": false
          }
        ]
      },
      "Methods": [
        "POST"
      ],
      "Body": {
        "Matcher": {
          "Name": "ProtoBufMatcher",
          "ContentMatcher": {
            "Name": "JsonPartialWildcardMatcher",
            "Pattern": {
              "name": "*"
            },
            "IgnoreCase": false,
            "Regex": false
          },
          "ProtoBufMessageType": "greet.HelloRequest"
        }
      }
    },
    "Response": {
      "BodyAsJson": {
        "message": "hello {{request.BodyAsJson.name}}"
      },
      "UseTransformer": true,
      "TransformerType": "Handlebars",
      "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert",
      "Headers": {
        "Content-Type": "application/grpc"
      },
      "TrailingHeaders": {
        "grpc-status": "0"
      },
      "ProtoBufMessageType": "greet.HelloReply"
    },
    "ProtoDefinition": "my-greeter"
  },
  {
    "Guid": "98fae52e-76df-47d9-876f-2ee32e931003",
    "UpdatedAt": "2024-12-21T07:10:12.6606835Z",
    "Request": {
      "Path": {
        "Matchers": [
          {
            "Name": "WildcardMatcher",
            "Pattern": "/grpc4/greet.Greeter/SayHello",
            "IgnoreCase": false
          }
        ]
      },
      "Methods": [
        "POST"
      ],
      "Body": {
        "Matcher": {
          "Name": "ProtoBufMatcher",
          "ProtoBufMessageType": "greet.HelloRequest"
        }
      }
    },
    "Response": {
      "BodyAsJson": {
        "message": "hello {{request.BodyAsJson.name}}"
      },
      "UseTransformer": true,
      "TransformerType": "Handlebars",
      "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert",
      "Headers": {
        "Content-Type": "application/grpc"
      },
      "TrailingHeaders": {
        "grpc-status": "0"
      },
      "ProtoBufMessageType": "greet.HelloReply"
    },
    "ProtoDefinition": "my-greeter"
  }
]
@StefH commented on GitHub (Dec 21, 2024): @GomesNayagam An example could be: ``` json [ { "Guid": "98fae52e-76df-47d9-876f-2ee32e931000", "UpdatedAt": "2024-12-21T07:10:12.6567323Z", "Request": { "Path": { "Matchers": [ { "Name": "WildcardMatcher", "Pattern": "/grpc/greet.Greeter/SayHello", "IgnoreCase": false } ] }, "Methods": [ "POST" ], "Body": { "Matcher": { "Name": "ProtoBufMatcher", "Pattern": "\r\nsyntax = \"proto3\";\r\n\r\npackage greet;\r\n\r\nservice Greeter {\r\n rpc SayHello (HelloRequest) returns (HelloReply);\r\n}\r\n\r\nmessage HelloRequest {\r\n string name = 1;\r\n}\r\n\r\nmessage HelloReply {\r\n string message = 1;\r\n}\r\n", "ContentMatcher": { "Name": "JsonPartialWildcardMatcher", "Pattern": { "name": "*" }, "IgnoreCase": false, "Regex": false }, "ProtoBufMessageType": "greet.HelloRequest" } } }, "Response": { "BodyAsJson": { "message": "hello {{request.BodyAsJson.name}}" }, "UseTransformer": true, "TransformerType": "Handlebars", "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert", "Headers": { "Content-Type": "application/grpc" }, "TrailingHeaders": { "grpc-status": "0" }, "ProtoDefinition": "\r\nsyntax = \"proto3\";\r\n\r\npackage greet;\r\n\r\nservice Greeter {\r\n rpc SayHello (HelloRequest) returns (HelloReply);\r\n}\r\n\r\nmessage HelloRequest {\r\n string name = 1;\r\n}\r\n\r\nmessage HelloReply {\r\n string message = 1;\r\n}\r\n", "ProtoBufMessageType": "greet.HelloReply" } }, { "Guid": "98fae52e-76df-47d9-876f-2ee32e931001", "UpdatedAt": "2024-12-21T07:10:12.6582715Z", "Request": { "Path": { "Matchers": [ { "Name": "WildcardMatcher", "Pattern": "/grpc2/greet.Greeter/SayHello", "IgnoreCase": false } ] }, "Methods": [ "POST" ], "Body": { "Matcher": { "Name": "ProtoBufMatcher", "ContentMatcher": { "Name": "JsonPartialWildcardMatcher", "Pattern": { "name": "*" }, "IgnoreCase": false, "Regex": false }, "ProtoBufMessageType": "greet.HelloRequest" } } }, "Response": { "BodyAsJson": { "message": "hello {{request.BodyAsJson.name}}" }, "UseTransformer": true, "TransformerType": "Handlebars", "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert", "Headers": { "Content-Type": "application/grpc" }, "TrailingHeaders": { "grpc-status": "0" }, "ProtoBufMessageType": "greet.HelloReply" }, "ProtoDefinition": "\r\nsyntax = \"proto3\";\r\n\r\npackage greet;\r\n\r\nservice Greeter {\r\n rpc SayHello (HelloRequest) returns (HelloReply);\r\n}\r\n\r\nmessage HelloRequest {\r\n string name = 1;\r\n}\r\n\r\nmessage HelloReply {\r\n string message = 1;\r\n}\r\n" }, { "Guid": "98fae52e-76df-47d9-876f-2ee32e931002", "UpdatedAt": "2024-12-21T07:10:12.6602685Z", "Request": { "Path": { "Matchers": [ { "Name": "WildcardMatcher", "Pattern": "/grpc3/greet.Greeter/SayHello", "IgnoreCase": false } ] }, "Methods": [ "POST" ], "Body": { "Matcher": { "Name": "ProtoBufMatcher", "ContentMatcher": { "Name": "JsonPartialWildcardMatcher", "Pattern": { "name": "*" }, "IgnoreCase": false, "Regex": false }, "ProtoBufMessageType": "greet.HelloRequest" } } }, "Response": { "BodyAsJson": { "message": "hello {{request.BodyAsJson.name}}" }, "UseTransformer": true, "TransformerType": "Handlebars", "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert", "Headers": { "Content-Type": "application/grpc" }, "TrailingHeaders": { "grpc-status": "0" }, "ProtoBufMessageType": "greet.HelloReply" }, "ProtoDefinition": "my-greeter" }, { "Guid": "98fae52e-76df-47d9-876f-2ee32e931003", "UpdatedAt": "2024-12-21T07:10:12.6606835Z", "Request": { "Path": { "Matchers": [ { "Name": "WildcardMatcher", "Pattern": "/grpc4/greet.Greeter/SayHello", "IgnoreCase": false } ] }, "Methods": [ "POST" ], "Body": { "Matcher": { "Name": "ProtoBufMatcher", "ProtoBufMessageType": "greet.HelloRequest" } } }, "Response": { "BodyAsJson": { "message": "hello {{request.BodyAsJson.name}}" }, "UseTransformer": true, "TransformerType": "Handlebars", "TransformerReplaceNodeOptions": "EvaluateAndTryToConvert", "Headers": { "Content-Type": "application/grpc" }, "TrailingHeaders": { "grpc-status": "0" }, "ProtoBufMessageType": "greet.HelloReply" }, "ProtoDefinition": "my-greeter" } ] ```
Author
Owner

@GomesNayagam commented on GitHub (Dec 27, 2024):

@StefH how do i use this in code like the wiremocktestcontainer support _files and _mapping, how could i use this. pls.

@GomesNayagam commented on GitHub (Dec 27, 2024): @StefH how do i use this in code like the wiremocktestcontainer support _files and _mapping, how could i use this. pls.
Author
Owner

@StefH commented on GitHub (Dec 27, 2024):

Just create a mappings.json file, add the mapping as json text and put this file somewhere.

Then see this example:
https://github.com/WireMock-Net/WireMock.Net/blob/master/examples/WireMock.Net.TestcontainersExample/Program.cs#L167

@StefH commented on GitHub (Dec 27, 2024): Just create a mappings.json file, add the mapping as json text and put this file somewhere. Then see this example: https://github.com/WireMock-Net/WireMock.Net/blob/master/examples/WireMock.Net.TestcontainersExample/Program.cs#L167
Author
Owner

@GomesNayagam commented on GitHub (Dec 27, 2024):

@StefH will grpc works with testcontainer? WireMockContainerBuilder? can you provide simple full e.g?

@GomesNayagam commented on GitHub (Dec 27, 2024): @StefH will grpc works with testcontainer? WireMockContainerBuilder? can you provide simple full e.g?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net-wiremock#652