From 510af92b4e4c75528e7c5827e3af527cd8bf7e59 Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Wed, 16 Jun 2021 16:21:41 +1000 Subject: [PATCH] feat: update readme on JUnit 5 WebFlux support #1373 --- provider/junit5spring/README.md | 31 ++++++++++- .../spring/junit5/WebfluxPactTest.java | 52 +++++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 provider/junit5spring/src/test/java/au/com/dius/pact/provider/spring/junit5/WebfluxPactTest.java diff --git a/provider/junit5spring/README.md b/provider/junit5spring/README.md index 468fa6b0f5..b8c8de420b 100644 --- a/provider/junit5spring/README.md +++ b/provider/junit5spring/README.md @@ -7,7 +7,7 @@ The combined library (JUnit5 + Spring) is available on maven central using: group-id = au.com.dius.pact.provider artifact-id = junit5spring -version-id = 4.1.x +version-id = 4.2.x ## Usage For writing Spring Pact verification tests with JUnit 5, there is an JUnit 5 Invocation Context Provider that you can use with @@ -108,13 +108,40 @@ class MockMvcTestTargetStandaloneMockMvcTestJava { **Important:** Since `@WebMvcTest` starts only Spring MVC components you can't use `PactVerificationSpringProvider` and need to fallback to `PactVerificationInvocationContextProvider` +## Webflux tests + +You can test Webflux routing functions using the `WebFluxTarget` target class. The easiest way to do it is to get Spring to +autowire your handler and router into the test and then pass the routing function to the target. + +For example: + +```java + @Autowired + YourRouter router; + + @Autowired + YourHandler handler; + + @BeforeEach + void setup(PactVerificationContext context) { + context.setTarget(new WebFluxTarget(router.route(handler))); + } + + @TestTemplate + @ExtendWith(PactVerificationSpringProvider.class) + void pactVerificationTestTemplate(PactVerificationContext context) { + context.verifyInteraction(); + } +``` + ## Modifying requests As documented in [Pact JUnit5 module](/provider/junit5/README.md#modifying-the-requests-before-they-are-sent), you can -inject a request object to modifiy the requests made. However, depending on the Pact test target you are using, +inject a request object to modify the requests made. However, depending on the Pact test target you are using, you need to use a different class. | Test Target | Class to use | |-------------|--------------| | HttpTarget, HttpsTarget, SpringBootHttpTarget | org.apache.http.HttpRequest | | MockMvcTestTarget | MockHttpServletRequestBuilder | +| WebFluxTarget | WebTestClient.RequestHeadersSpec | diff --git a/provider/junit5spring/src/test/java/au/com/dius/pact/provider/spring/junit5/WebfluxPactTest.java b/provider/junit5spring/src/test/java/au/com/dius/pact/provider/spring/junit5/WebfluxPactTest.java new file mode 100644 index 0000000000..1efac7882d --- /dev/null +++ b/provider/junit5spring/src/test/java/au/com/dius/pact/provider/spring/junit5/WebfluxPactTest.java @@ -0,0 +1,52 @@ +package au.com.dius.pact.provider.spring.junit5; + +import au.com.dius.pact.provider.junit5.PactVerificationContext; +import au.com.dius.pact.provider.junitsupport.Provider; +import au.com.dius.pact.provider.junitsupport.loader.PactFolder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +@Provider("myAwesomeService") +@PactFolder("pacts") +public class WebfluxPactTest { + + public static class Handler { + public Mono handleRequest(ServerRequest request) { + return ServerResponse.noContent().build(); + } + } + + static class Router { + public RouterFunction route(Handler handler) { + return RouterFunctions + .route(RequestPredicates.GET("/data").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), + handler::handleRequest) + .andRoute(RequestPredicates.GET("/async-data").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), + handler::handleRequest); + } + } + + @BeforeEach + void setup(PactVerificationContext context) { + Handler handler = new Handler(); + context.setTarget(new WebFluxTarget(new Router().route(handler))); + } + + @TestTemplate + @ExtendWith(PactVerificationSpringProvider.class) + void pactVerificationTestTemplate(PactVerificationContext context) { + context.verifyInteraction(); + } +}