Skip to content

Commit

Permalink
Implement support for duplex streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
cezarypiatek committed Jun 17, 2023
1 parent 7a6670b commit 7c087f2
Show file tree
Hide file tree
Showing 10 changed files with 744 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,4 @@ FodyWeavers.xsd

# JetBrains Rider
*.sln.iml
src/.idea
79 changes: 68 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# GRPC-Mock-Server
Super fast, platform independent, standalone component for mocking GRPC services using [WireMock.NET](https://github.com/WireMock-Net/WireMock.Net) stubbing engine

## Supported GRPC communication patterns

|Pattern|Implementation status|
|---|----|
|request-reply||
|server-streaming||
|client-streaming||
|duplex-streaming||

## How does it work

GRPC-Mock-Server works in the following way:
Expand Down Expand Up @@ -224,6 +233,38 @@ await grpcMockClient.MockClientStreaming
},
response: new { message = "Hi there streaming client" }
);

await grpcMockClient.MockDuplexStreaming
(
serviceName: "my.package.Sample",
methodName: "TestClientServerStreaming",
scenario: new MessageExchange[]
{
new ()
{
Requests = new[]
{
new {name = "Ping 1a"},
new {name = "Ping 1b"}
},
Responses = new[]
{
new {message = "Pong 1"}
}
},
new ()
{
Requests = new[]
{
new {name = "Ping 2"},
},
Responses = new[]
{
new {message = "Pong 2a"},
new {message = "Pong 2b"}
}
},
});
```

You can also generate stub helpers that will simplify your code responsible for preparing mocks/stubs.
Expand Down Expand Up @@ -278,19 +319,35 @@ _ = await mockHelper.MockTestClientStreaming
}
);

_ = await mockHelper.MockTestClientServerStreaming(new MessageExchange<HelloRequest, HelloReply>[]
{
new()
{
Requests = new HelloRequest[]
{
new() {Name = "Ping 1a"},
new() {Name = "Ping 1b"}
},
Responses = new HelloReply[]
{
new() {Message = "Pong 1"}
}
},
new()
{
Requests = new HelloRequest[]
{
new() {Name = "Ping 2"},
},
Responses = new HelloReply[]
{
new() {Message = "Pong 2a"},
new() {Message = "Pong 2b"}
}
},
});
```


## Supported GRPC communication patterns

|Pattern|Implementation status|
|---|----|
|request-reply||
|server-streaming||
|client-streaming||
|duplex-streaming||


## TODO
- [ ] Implement error response codes
- [x] Stub generator
Expand Down
141 changes: 99 additions & 42 deletions src/GrpcTestKit.Demo/Tests.cs → src/GrpcTestKit.Demo/Examples.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using System.Diagnostics;
using System.Net;
using System.Text.Json;
using System.Text.Json.Serialization;
using Grpc.Core;
using Grpc.Net.Client;
using GrpcTestKit.TestConnectors;
using GrpcTestKit.TestConnectors.Docker;
using GrpcTestKit.TestConnectors.Kubernetes;
using My.Package;

namespace GrpcTestKit.Demo
{

[Explicit]
public class Tests
public class Examples
{
[Test]
public async Task test_with_testcontainers()
Expand Down Expand Up @@ -129,48 +132,100 @@ public async Task test_with_inmemoryconnector()

var grpcMockClient = connector.CreateClient();

await grpcMockClient.MockRequestReply
(
serviceName: "my.package.Sample",
methodName: "TestRequestReply",
request: new { name = "Hello 1" },
response: new { message = "Hi there 1" }
);

await grpcMockClient.MockRequestReply
(
serviceName: "my.package.Sample",
methodName: "TestRequestReply",
request: new { name = "Hello 2" },
response: new { message = "Hi there 2" }
);

await grpcMockClient.MockServerStreaming
(
serviceName: "my.package.Sample",
methodName: "TestServerStreaming",
request: new { name = "Hello streaming" },
response: new[]
{
new {message = "Hi there 1"},
new {message = "Hi there 2"},
new {message = "Hi there 3"}
}
);

await grpcMockClient.MockClientStreaming
(
// await grpcMockClient.MockRequestReply
// (
// serviceName: "my.package.Sample",
// methodName: "TestRequestReply",
// request: new { name = "Hello 1" },
// response: new { message = "Hi there 1" }
// );
//
// await grpcMockClient.MockRequestReply
// (
// serviceName: "my.package.Sample",
// methodName: "TestRequestReply",
// request: new { name = "Hello 2" },
// response: new { message = "Hi there 2" }
// );
//
// await grpcMockClient.MockServerStreaming
// (
// serviceName: "my.package.Sample",
// methodName: "TestServerStreaming",
// request: new { name = "Hello streaming" },
// response: new[]
// {
// new {message = "Hi there 1"},
// new {message = "Hi there 2"},
// new {message = "Hi there 3"}
// }
// );
//
// await grpcMockClient.MockClientStreaming
// (
// serviceName: "my.package.Sample",
// methodName: "TestServerStreaming",
// request: new []
// {
// new { name = "Hello streaming 1" },
// new { name = "Hello streaming 2" }
// },
// response: new { message = "Hi there streaming client" }
// );

await grpcMockClient.MockDuplexStreaming(
serviceName: "my.package.Sample",
methodName: "TestServerStreaming",
request: new []
methodName: "TestClientServerStreaming",
scenario: new MessageExchange[]
{
new { name = "Hello streaming 1" },
new { name = "Hello streaming 2" }
},
response: new { message = "Hi there streaming client" }
);


new ()
{
Requests = new[]
{
new {name = "Ping 1a"},
new {name = "Ping 1b"}
},
Responses = new[]
{
new {message = "Pong 1"}
}
},
new ()
{
Requests = new[]
{
new {name = "Ping 2"},
},
Responses = new[]
{
new {message = "Pong 2a"},
new {message = "Pong 2b"}
}
},
});
var channel = GrpcChannel.ForAddress(connectionInfo.GrpcEndpoint);
var client = new Sample.SampleClient(channel);



var call = client.TestClientServerStreaming();
await call.RequestStream.WriteAsync(new HelloRequest
{
Name = "Ping 1a"
});
await call.RequestStream.WriteAsync(new HelloRequest
{
Name = "Ping 1b"
});
await call.ResponseStream.MoveNext();
await call.RequestStream.WriteAsync(new HelloRequest
{
Name = "Ping 2"
});

await call.RequestStream.CompleteAsync();
await call.ResponseStream.MoveNext();
await call.ResponseStream.MoveNext();
grpcMockClient.Inspect();
}

Expand Down Expand Up @@ -230,4 +285,6 @@ public partial class SampleMockHelper
{

}


}
5 changes: 3 additions & 2 deletions src/GrpcTestKit.Demo/GrpcTestKit.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="NScenario" Version="4.3.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
Expand All @@ -21,7 +22,7 @@

<ItemGroup>
<ProjectReference Include="..\GrpcTestKit\GrpcTestKit.csproj" />
<ProjectReference Include="..\GrpcToRestGenerator\GrpcTestKit.GrpcMockServerGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
<ProjectReference Include="..\GrpcToRestGenerator\GrpcTestKit.GrpcMockServerGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

<ItemGroup>
Expand All @@ -31,6 +32,6 @@
</ItemGroup>

<ItemGroup>
<Protobuf Include="protos\**\*.proto" GrpcServices="Server" />
<Protobuf Include="protos\**\*.proto" GrpcServices="Both" />
</ItemGroup>
</Project>
Loading

0 comments on commit 7c087f2

Please sign in to comment.