From 0ee8cd719af2bc12ff011fdddcb0cf8d59e3cedf Mon Sep 17 00:00:00 2001 From: Eric Deandrea Date: Thu, 18 Jan 2024 08:46:15 -0500 Subject: [PATCH] Add resetAll method to WireMockGrpcService (#27) --- .../grpc/dsl/WireMockGrpcService.java | 23 +++++++- .../org/wiremock/grpc/GrpcAcceptanceTest.java | 53 ++++++++++++++++-- src/test/proto/ExampleServices.proto | 7 +++ src/test/resources/wiremock/grpc/services.dsc | Bin 1411 -> 1840 bytes .../wiremock/mappings/hello-world.json | 37 ++++++++++++ 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/wiremock/mappings/hello-world.json diff --git a/src/main/java/org/wiremock/grpc/dsl/WireMockGrpcService.java b/src/main/java/org/wiremock/grpc/dsl/WireMockGrpcService.java index 2daadd5..840ed38 100644 --- a/src/main/java/org/wiremock/grpc/dsl/WireMockGrpcService.java +++ b/src/main/java/org/wiremock/grpc/dsl/WireMockGrpcService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Thomas Akehurst + * Copyright (C) 2023-2024 Thomas Akehurst * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import com.github.tomakehurst.wiremock.client.CountMatchingStrategy; import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.http.RequestMethod; +import com.github.tomakehurst.wiremock.matching.RequestPattern; import com.github.tomakehurst.wiremock.stubbing.StubMapping; import org.wiremock.annotations.Beta; @@ -51,4 +53,23 @@ public GrpcVerification verify(int count, String method) { public GrpcVerification verify(CountMatchingStrategy countMatch, String method) { return new GrpcVerification(wireMock, countMatch, serviceName, method); } + + /** Removes all transient stubs for the current gRPC service */ + public void removeAllStubs() { + final String servicePath = "/" + serviceName; + + wireMock.allStubMappings().getMappings().stream() + .filter( + mapping -> { + final RequestPattern requestMatcher = mapping.getRequest(); + final RequestMethod requestMethod = requestMatcher.getMethod(); + final String requestPath = requestMatcher.getUrlPath(); + + return (requestMethod != null) + && (requestPath != null) + && requestMethod.match(RequestMethod.POST).isExactMatch() + && requestPath.startsWith(servicePath); + }) + .forEach(wireMock::removeStubMapping); + } } diff --git a/src/test/java/org/wiremock/grpc/GrpcAcceptanceTest.java b/src/test/java/org/wiremock/grpc/GrpcAcceptanceTest.java index ef1929f..53bc240 100644 --- a/src/test/java/org/wiremock/grpc/GrpcAcceptanceTest.java +++ b/src/test/java/org/wiremock/grpc/GrpcAcceptanceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Thomas Akehurst + * Copyright (C) 2023-2024 Thomas Akehurst * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,11 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.wiremock.grpc.dsl.WireMockGrpc.*; +import com.example.grpc.AnotherGreetingServiceGrpc; import com.example.grpc.GreetingServiceGrpc; import com.example.grpc.request.HelloRequest; import com.example.grpc.response.HelloResponse; @@ -34,6 +36,7 @@ import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; import java.time.Duration; +import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -46,6 +49,7 @@ public class GrpcAcceptanceTest { WireMockGrpcService mockGreetingService; ManagedChannel channel; GreetingsClient greetingsClient; + WireMock wireMock; @RegisterExtension public static WireMockExtension wm = @@ -59,8 +63,8 @@ public class GrpcAcceptanceTest { @BeforeEach void init() { - mockGreetingService = - new WireMockGrpcService(new WireMock(wm.getPort()), GreetingServiceGrpc.SERVICE_NAME); + wireMock = wm.getRuntimeInfo().getWireMock(); + mockGreetingService = new WireMockGrpcService(wireMock, GreetingServiceGrpc.SERVICE_NAME); channel = ManagedChannelBuilder.forAddress("localhost", wm.getPort()).usePlaintext().build(); greetingsClient = new GreetingsClient(channel); @@ -254,7 +258,7 @@ void networkFault() { Exception exception = assertThrows(StatusRuntimeException.class, () -> greetingsClient.greet("Alan")); - assertThat(exception.getMessage(), is("UNKNOWN")); + assertThat(exception.getMessage(), startsWith("UNKNOWN")); } @Test @@ -286,4 +290,45 @@ void randomDelay() { assertThat(greeting, is("Delayed hello")); assertThat(stopwatch.elapsed(), greaterThanOrEqualTo(Duration.ofMillis(500L))); } + + @Test + void resetStubs() { + // Starting point assertion + // There should be a single mapping (the hello-world one) + verifyDefaultMappings(); + + WireMockGrpcService mockAnotherGreetingService = + new WireMockGrpcService(wireMock, AnotherGreetingServiceGrpc.SERVICE_NAME); + + mockAnotherGreetingService.stubFor( + method("greeting").willReturn(message(HelloResponse.newBuilder().setGreeting("Hi")))); + + mockGreetingService.stubFor( + method("greeting").willReturn(message(HelloResponse.newBuilder().setGreeting("Hi")))); + + mockGreetingService.stubFor( + method("oneGreetingEmptyReply").willReturn(message(Empty.newBuilder()))); + + assertThat(wireMock.allStubMappings().getMappings(), iterableWithSize(4)); + + mockGreetingService.removeAllStubs(); + assertThat(wireMock.allStubMappings().getMappings(), iterableWithSize(2)); + + mockAnotherGreetingService.removeAllStubs(); + + verifyDefaultMappings(); + } + + private void verifyDefaultMappings() { + var mappings = wireMock.allStubMappings().getMappings(); + assertThat(mappings, iterableWithSize(1)); + + var mapping = mappings.get(0); + assertNotNull(mapping); + assertThat(mapping.getName(), Matchers.equalTo("Hello")); + + var request = mapping.getRequest(); + assertThat(request.getMethod().value(), Matchers.equalTo("GET")); + assertThat(request.getUrlPath(), Matchers.equalTo("/hello")); + } } diff --git a/src/test/proto/ExampleServices.proto b/src/test/proto/ExampleServices.proto index 9b20251..f565f52 100644 --- a/src/test/proto/ExampleServices.proto +++ b/src/test/proto/ExampleServices.proto @@ -31,3 +31,10 @@ service GreetingService { rpc oneGreetingManyReplies(com.example.grpc.request.HelloRequest) returns (stream com.example.grpc.response.HelloResponse); rpc oneGreetingEmptyReply(com.example.grpc.request.HelloRequest) returns (google.protobuf.Empty); } + +service AnotherGreetingService { + rpc greeting(com.example.grpc.request.HelloRequest) returns (com.example.grpc.response.HelloResponse); + rpc manyGreetingsOneReply(stream com.example.grpc.request.HelloRequest) returns (com.example.grpc.response.HelloResponse); + rpc oneGreetingManyReplies(com.example.grpc.request.HelloRequest) returns (stream com.example.grpc.response.HelloResponse); + rpc oneGreetingEmptyReply(com.example.grpc.request.HelloRequest) returns (google.protobuf.Empty); +} \ No newline at end of file diff --git a/src/test/resources/wiremock/grpc/services.dsc b/src/test/resources/wiremock/grpc/services.dsc index 49332532ee8cc40301aa1b960489671f1bfdcabf..df663d27c5d3ddd44dad6be7c2ef111fb71dae2c 100644 GIT binary patch delta 33 pcmZqX-oUrPpPA`C`{qDqH6|XTRm@ysj(Pbd8L35^uQ9J>1OTZ63VZ+n delta 28 jcmdnM*UY`apP6YB%jQ64H6|V>rU1qywt}Mkl6+$TaUBPy diff --git a/src/test/resources/wiremock/mappings/hello-world.json b/src/test/resources/wiremock/mappings/hello-world.json new file mode 100644 index 0000000..66bd934 --- /dev/null +++ b/src/test/resources/wiremock/mappings/hello-world.json @@ -0,0 +1,37 @@ +{ + "mappings": [{ + "request": { + "headers": {"Accept": {"or": [ + {"equalTo": "*/*"}, + {"equalTo": "text/plain"} + ]}}, + "method": "GET", + "urlPath": "/hello" + }, + "metadata": {"mocklab": { + "response-example-attachment": "Hello World", + "created": { + "at": "2024-01-09T15:32:35.424189986Z", + "by": "vqe9q", + "via": "ADMIN_API" + }, + "updated": { + "at": "2024-01-09T15:34:11.584464236Z", + "by": "vqe9q", + "via": "ADMIN_API" + } + }}, + "response": { + "headers": {"Content-Type": "text/plain"}, + "body": "Hello World!", + "status": 200 + }, + "name": "Hello", + "postServeActions": [], + "id": "d469c289-22fb-4186-90ab-deb6ffb6db5c", + "persistent": true, + "priority": 5, + "uuid": "d469c289-22fb-4186-90ab-deb6ffb6db5c" + }], + "meta": {"total": 1} +}