I am new to Pact contract testing
Gradle dependencies
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
//pact
testImplementation 'au.com.dius.pact.consumer:junit5:4.3.6'
}
Rest Controller
@RestController
public class CodeController {
@GetMapping("/hello")
public String hello() {
return "Hello from spring with pact project";
}
}
ControllerClient
@Component
public class ControllerClient{
private final RestTemplate restTemplate;
public ControllerClient(@Value("${user-service.base-url}") String baseUrl) {
this.restTemplate = new RestTemplateBuilder().rootUri(baseUrl).build();
}
public String getHello() {
return restTemplate.getForObject("/hello", String.class);
}
}
ConsumerContractTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = "user-service.base-url:http://localhost:8080", classes = ControllerClient.class)
@ExtendWith(PactConsumerTestExt.class)
public class ConsumerContractTest {
@Autowired
private ControllerClient controllerClient;
@Pact(consumer = "code-consumer")
public RequestResponsePact pactForHelloWorld(PactDslWithProvider builder) {
return builder
.given("hello world")
.uponReceiving("hello request")
.path("/hello")
.method(HttpMethod.GET.name())
.willRespondWith().status(200)
.body(new PactDslJsonBody().stringType("Hello from spring with pact project"))
.toPact();
}
@PactTestFor(pactMethod = "pactForHelloWorld", pactVersion = PactSpecVersion.V3)
@Test
public void userExists() {
String returnStr = controllerClient.getHello();
assertThat(returnStr).isEqualTo("Hello from spring with pact project");
}
}
When I execute this consumer contract test I get below exception
au.com.dius.pact.consumer.PactMismatchesException: The following requests were not received:
method: GET
path: /hello
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:468)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterTestExecutionCallbacks$9(TestMethodTestDescriptor.java:233)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:273)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$14(TestMethodTestDescriptor.java:273)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
....
The issue is that your test doesn't send the request to the Pact mock service - that's why you're getting the error "The following requests were not received".
You should modify your unit test as follows:
@PactTestFor(pactMethod = "pactForHelloWorld", pactVersion = PactSpecVersion.V3)
@Test
public void userExists(MockServer mockServer) {
// TODO: set endpoint on controllerClient to mockServer.getUrl()
String returnStr = controllerClient.getHello();
assertThat(returnStr).isEqualTo("Hello from spring with pact project");
}
See an example of this approach here.