I am following this Pact github tutorial and stuck in one of the scenarios.
Pact links Model 1 : Pact JVM
Model 2 : Junit 5
I am fudging both, but for this test I am inclined to use Model2 ( but using react)
@Pact(consumer = "ProductCatalogue")
public RequestResponsePact singleProductNotExists(PactDslWithProvider builder) {
return builder
.given("product with ID 10 does not exist", "id", 10)
.uponReceiving("get product with ID 10")
.path("/product/10")
.willRespondWith()
.headers(Map.of("Content-Type", "application/json"))
.status(404)
.toPact();
}
@Test
@PactTestFor(pactMethod = "singleProductNotExists", pactVersion = PactSpecVersion.V3)
void testSingleProductNotExists(MockServer mockServer) {
WebClient webClient = WebClient.builder().baseUrl(mockServer.getUrl()).build();
productService = new ProductService(webClient);
try {
productService.getProductById(10);
fail("Expected service call to throw an exception");
} catch (HttpClientErrorException ex) {
assertThat(ex.getMessage(), containsString("404 Not Found"));
}
}
Error:
[INFO]
[ERROR] Failures:
[ERROR] ProductServiceClientPactTest.testSingleProductNotExists:190 Expected service call to throw an exception
[INFO]
[ERROR] Tests run: 4, Failures: 1, Errors: 0, Skipped: 0
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.896 s <<< FAILURE! -- in com.example.ProductServiceClientPactTest
[ERROR] com.example.ProductServiceClientPactTest.testSingleProductNotExists(MockServer) -- Time elapsed: 1.805 s <<< FAILURE!
java.lang.AssertionError: Expected service call to throw an exception
at com.example.ProductServiceClientPactTest.testSingleProductNotExists(ProductServiceClientPactTest.java:190)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Suppressed: au.com.dius.pact.consumer.PactMismatchesException: The following requests were not received:
method: GET
path: /product/10
query: {}
headers: {}
matchers: MatchingRules(rules={})
generators: Generators(categories={})
body: MISSING
at au.com.dius.pact.consumer.junit.JUnitTestSupport.validateMockServerResult(JUnitTestSupport.kt:110)
at au.com.dius.pact.consumer.junit5.PactConsumerTestExt.afterTestExecution(PactConsumerTestExt.kt:631)
... 2 more
Not sure if I have to follow the same non-reactive approach i.e. expecting exception or do something different.
Goal is to overcome this issue and get pact file created. Please advice
I have to say it is my implementation mistake I had to update service to do the below
.onStatus(HttpStatusCode::is4xxClientError, response -> Mono.error(new HttpClientErrorException(HttpStatus.NOT_FOUND)))
Full method code
return webClient.get()
.uri("/product/{id}", id)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, response -> Mono.error(new HttpClientErrorException(HttpStatus.NOT_FOUND)))
.bodyToMono(Product.class);
and update test to use block()
productService.getProductById(10).block();
Alternately StepVerifier can be used to verify .expectErrorMatches
*
P.S. I did tried onStatus before, but that did not work probably because I did not use block() call in pact test - .onStatus(HttpStatusCode::isError, response -> Mono.error(new Exception(response.toString())))