|
| 1 | +using System; |
1 | 2 | using System.Text.Json; |
2 | 3 | using System.Threading.Tasks; |
3 | 4 | using FluentAssertions; |
4 | 5 | using Xunit; |
5 | | -using PactNet.Interop; |
6 | 6 | using System.IO; |
| 7 | +using System.Text.Json.Serialization; |
7 | 8 | using PactNet; |
| 9 | +using PactNet.Exceptions; |
| 10 | +using PactNet.Extensions.Grpc; |
| 11 | +using PactNet.Output.Xunit; |
8 | 12 | using Xunit.Abstractions; |
9 | 13 |
|
10 | 14 | namespace GrpcGreeterClient.Tests |
11 | 15 | { |
12 | | - public class GrpcGreeterClientTests |
| 16 | + public class GrpcGreeterClientTests : IDisposable |
13 | 17 | { |
14 | | - private readonly ITestOutputHelper testOutputHelper; |
| 18 | + private readonly IGrpcPactBuilderV4 pact; |
15 | 19 |
|
16 | | - public GrpcGreeterClientTests(ITestOutputHelper testOutputHelper) |
| 20 | + public GrpcGreeterClientTests(ITestOutputHelper output) |
17 | 21 | { |
18 | | - this.testOutputHelper = testOutputHelper; |
19 | | - PactLogLevel.Information.InitialiseLogging(); |
| 22 | + var config = new PactConfig |
| 23 | + { |
| 24 | + PactDir = "../../../../pacts/", |
| 25 | + Outputters = new[] |
| 26 | + { |
| 27 | + new XunitOutput(output) |
| 28 | + }, |
| 29 | + DefaultJsonSettings = new JsonSerializerOptions |
| 30 | + { |
| 31 | + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, |
| 32 | + PropertyNameCaseInsensitive = true, |
| 33 | + Converters = { new JsonStringEnumConverter() } |
| 34 | + }, |
| 35 | + LogLevel = PactLogLevel.Debug |
| 36 | + }; |
| 37 | + |
| 38 | + this.pact = Pact.V4("grpc-greeter-client", "grpc-greeter", config).WithGrpcInteractions(); |
20 | 39 | } |
21 | 40 |
|
22 | 41 | [Fact] |
23 | | - public async Task ReturnsMismatchWhenNoGrpcClientRequestMade() |
| 42 | + public void ThrowsExceptionWhenNoGrpcClientRequestMade() |
24 | 43 | { |
25 | | - // arrange |
26 | | - var host = "0.0.0.0"; |
27 | | - var pact = NativeInterop.NewPact("grpc-greeter-client", "grpc-greeter"); |
28 | | - var interaction = PluginInterop.NewSyncMessageInteraction(pact, "a request to a plugin"); |
29 | | - NativeInterop.WithSpecification(pact, PactSpecification.V4); |
30 | | - var content = $@"{{ |
31 | | - ""pact:proto"":""{Path.Join(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "GrpcGreeterClient", "Protos", "greet.proto").Replace("\\", "\\\\")}"", |
32 | | - ""pact:proto-service"": ""Greeter/SayHello"", |
33 | | - ""pact:content-type"": ""application/protobuf"", |
34 | | - ""request"": {{ |
35 | | - ""name"": ""matching(type, 'foo')"" |
36 | | - }}, |
37 | | - ""response"": {{ |
38 | | - ""message"": ""matching(type, 'Hello foo')"" |
39 | | - }} |
40 | | - }}"; |
41 | | - |
42 | | - using var pluginDriver = pact.UsePlugin("protobuf", "0.4.0"); |
43 | | - PluginInterop.PluginInteractionContents(interaction, 0, "application/grpc", content); |
44 | | - |
45 | | - using var driver = pact.CreateMockServer(host, 0, "grpc", false); |
46 | | - var port = driver.Port; |
47 | | - testOutputHelper.WriteLine("Port: " + port); |
48 | | - |
49 | | - var matched = driver.MockServerMatched(); |
50 | | - testOutputHelper.WriteLine("Matched: " + matched); |
51 | | - matched.Should().BeFalse(); |
52 | | - |
53 | | - var MismatchesString = driver.MockServerMismatches(); |
54 | | - testOutputHelper.WriteLine("Mismatches: " + MismatchesString); |
55 | | - var MismatchesJson = JsonSerializer.Deserialize<JsonElement>(MismatchesString); |
56 | | - var ErrorString = MismatchesJson[0].GetProperty("error").GetString(); |
57 | | - var ExpectedPath = MismatchesJson[0].GetProperty("path").GetString(); |
58 | | - |
59 | | - ErrorString.Should().Be("Did not receive any requests for path 'Greeter/SayHello'"); |
60 | | - ExpectedPath.Should().Be("Greeter/SayHello"); |
61 | | - |
62 | | - await Task.Delay(1); |
| 44 | + string protoFilePath = Path.Join(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "GrpcGreeterClient", "Protos", "greet.proto"); |
| 45 | + this.pact |
| 46 | + .UponReceiving("A greeting request to say hello.") |
| 47 | + .WithRequest(protoFilePath, nameof(Greeter), "SayHello", |
| 48 | + new { name = "matching(type, 'foo')" }) |
| 49 | + .WillRespond() |
| 50 | + .WithBody(new { message = "matching(type, 'Hello foo')" }); |
| 51 | + |
| 52 | + Assert.Throws<PactFailureException>(() => |
| 53 | + this.pact.Verify(ctx => |
| 54 | + { |
| 55 | + // No grpc call here results in failure. |
| 56 | + })); |
63 | 57 | } |
| 58 | + |
64 | 59 | [Fact] |
65 | | - public async Task WritesPactWhenGrpcClientRequestMade() |
| 60 | + public async Task WritesPactForGreeterSayHelloRequest() |
66 | 61 | { |
67 | | - // arrange |
68 | | - var host = "0.0.0.0"; |
69 | | - var pact = NativeInterop.NewPact("grpc-greeter-client", "grpc-greeter"); |
70 | | - var interaction = PluginInterop.NewSyncMessageInteraction(pact, "a request to a plugin"); |
71 | | - NativeInterop.WithSpecification(pact, PactSpecification.V4); |
72 | | - var content = $@"{{ |
73 | | - ""pact:proto"":""{Path.Join(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "GrpcGreeterClient", "Protos", "greet.proto").Replace("\\", "\\\\")}"", |
74 | | - ""pact:proto-service"": ""Greeter/SayHello"", |
75 | | - ""pact:content-type"": ""application/protobuf"", |
76 | | - ""request"": {{ |
77 | | - ""name"": ""matching(type, 'foo')"" |
78 | | - }}, |
79 | | - ""response"": {{ |
80 | | - ""message"": ""matching(type, 'Hello foo')"" |
81 | | - }} |
82 | | - }}"; |
83 | | - |
84 | | - using var pluginDriver = pact.UsePlugin("protobuf", "0.4.0"); |
85 | | - PluginInterop.PluginInteractionContents(interaction, 0, "application/grpc", content); |
86 | | - |
87 | | - using var driver = pact.CreateMockServer(host, 0, "grpc", false); |
88 | | - var port = driver.Port; |
89 | | - testOutputHelper.WriteLine("Port: " + port); |
90 | | - |
91 | | - // act |
92 | | - var client = new GreeterClientWrapper("http://localhost:" + port); |
93 | | - var result = await client.SayHello("foo"); |
94 | | - testOutputHelper.WriteLine("Result: " + result); |
95 | | - |
96 | | - // assert |
97 | | - result.Should().Be("Hello foo"); |
98 | | - var matched = driver.MockServerMatched(); |
99 | | - testOutputHelper.WriteLine("Matched: " + matched); |
100 | | - matched.Should().BeTrue(); |
101 | | - |
102 | | - var MismatchesString = driver.MockServerMismatches(); |
103 | | - testOutputHelper.WriteLine("Mismatches: " + MismatchesString); |
104 | | - |
105 | | - MismatchesString.Should().Be("[]"); |
106 | | - |
107 | | - PactFileWriter.WritePactFileForPort(port, "../../../../pacts"); |
| 62 | + // Arrange |
| 63 | + string protoFilePath = Path.Join(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "GrpcGreeterClient", "Protos", "greet.proto"); |
| 64 | + this.pact |
| 65 | + .UponReceiving("A greeting request to say hello.") |
| 66 | + .WithRequest(protoFilePath, nameof(Greeter), "SayHello", |
| 67 | + new { name = "matching(type, 'foo')" }) |
| 68 | + .WillRespond() |
| 69 | + .WithBody(new { message = "matching(type, 'Hello foo')" }); |
| 70 | + |
| 71 | + await this.pact.VerifyAsync(async ctx => |
| 72 | + { |
| 73 | + |
| 74 | + // Arrange |
| 75 | + var client = new GreeterClientWrapper(ctx.MockServerUri.AbsoluteUri); |
| 76 | + |
| 77 | + // Act |
| 78 | + var greeting = await client.SayHello("foo"); |
| 79 | + |
| 80 | + // Assert |
| 81 | + greeting.Should().Be("Hello foo"); |
| 82 | + }); |
108 | 83 | } |
109 | 84 |
|
| 85 | + public void Dispose() => this.pact?.Dispose(); |
110 | 86 | } |
111 | 87 | } |
0 commit comments