I developed a REST API Quarkus project based on an OpenAPI specification to validate contract testing with Microcks.
OpenAPI Specification
openapi: 3.0.0
x-stoplight:
id: 1q8257l49074g
info:
title: SampleAPI
version: '1.0'
description: |-
A sample API demonstrating OpenAPI 3.0 and Microcks integration.
license:
name: Apache 2.0
paths:
/sender:
get:
tags:
- Sender
summary: Get All Senders
description: Retrieves all sender entries.
operationId: getAllSenders
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SenderResult'
examples:
all:
value:
- id: 1
message: "Hello Receiver"
status: "sent"
- id: 2
message: "Another message"
status: "pending"
'500':
description: Internal server error
content:
text/plain:
schema:
type: string
example: "Internal Server Error"
components:
schemas:
SenderResult:
type: object
required:
- id
- message
- status
properties:
id:
type: integer
message:
type: string
status:
type: string
Resource Class
@Slf4j
@ApplicationScoped
public class SenderResource implements SenderApi {
private final ReceiverClient receiverClient;
// Simple in-memory cache simulating a database
private final ConcurrentHashMap<Integer, SenderResult> senderCache = new ConcurrentHashMap<>();
@Inject
public SenderResource(@RestClient ReceiverClient receiverClient) {
this.receiverClient = receiverClient;
log.info("Initializing SenderResource...");
// Default sender entry
SenderResult defaultSender = new SenderResult()
.id(1)
.message("default")
.status("success");
senderCache.put(defaultSender.getId(), defaultSender);
// Another example sender
SenderResult anotherSender = new SenderResult()
.id(2)
.message("another")
.status("QUEUED");
senderCache.put(anotherSender.getId(), anotherSender);
}
/**
* Retrieve all senders.
*/
@Override
public Response getAllSenders() {
return Response.ok(senderCache.values()).build();
}
}
Microcks Configuration
To enable Microcks integration, I added the following configuration in application.yaml:
quarkus:
microcks:
devservices:
enabled: true
And included the Quarkus Microcks dependency:
<dependency>
<groupId>io.github.microcks.quarkus</groupId>
<artifactId>quarkus-microcks</artifactId>
<version>0.4.1</version>
<scope>test</scope>
</dependency>
Contract Test
To verify that everything works, I created a contract test using Microcks:
@QuarkusTest
@Slf4j
public class SenderContractTest {
static String microcksUrl;
static Integer port;
@BeforeAll
static void init() {
Config config = ConfigProvider.getConfig();
microcksUrl = config
.getOptionalValue("quarkus.microcks.default.http", String.class)
.orElse("http://localhost:8085");
port = config.getOptionalValue("quarkus.http.test-port", Integer.class)
.orElse(8282);
log.info("Microcks URL for contract tests: {}", microcksUrl);
log.info("Test application port: {}", port);
}
@Test
void testAllOperationsFromSenderOpenApi() throws Exception {
String endpointUrl = "http://host.containers.internal:" + port;
log.info("Endpoint URL for contract test: {}", endpointUrl);
TestRequest request = new TestRequest.Builder()
.serviceId("SenderAPI:1.0")
.runnerType(TestRunnerType.OPEN_API_SCHEMA)
.testEndpoint(endpointUrl)
.build();
TestResult result = MicrocksContainer.testEndpoint(microcksUrl, request);
assertNotNull(result, "A test result should be returned by Microcks");
logTestResultDetails(result);
assertTrue(result.isSuccess(), "Contract test failed. See logs above for details.");
assertEquals(5, result.getTestCaseResults().size(),
"Number of test cases should match the number of operations (GET all, GET by ID, POST, DELETE)");
}
}
for the unit test was successfull
Integration Test Issue
However, when running the integration tests, I encountered the following error:
Server Version: 5.2.5
API Version: 1.41
Operating System: Fedora
Total Memory: 7358 MB
2025-10-08 17:24:34,176 WARN [org.tes.uti.ResourceReaper] (build-9)
********************************************************************************
Ryuk has been disabled. This can cause unexpected behavior in your environment.
********************************************************************************
2025-10-08 17:24:34,177 INFO [org.tes.DockerClientFactory] (build-9) Checking the system...
2025-10-08 17:24:34,178 INFO [org.tes.DockerClientFactory] (build-9) ✔︎ Docker server version should be at least 1.6.0
2025-10-08 17:24:34,181 INFO [org.tes.ima.PullPolicy] (build-9) Image pull policy will be performed by: DefaultPullPolicy()
2025-10-08 17:24:34,182 INFO [org.tes.uti.ImageNameSubstitutor] (build-9) Using DefaultImageNameSubstitutor
2025-10-08 17:24:34,370 INFO [tc.tes.2.0] (build-9) Creating container for image: testcontainers/sshd:1.2.0
2025-10-08 17:24:34,700 INFO [tc.tes.2.0] (build-9) Container testcontainers/sshd:1.2.0 started in PT0.33S
2025-10-08 17:24:34,740 INFO [tc.qua.io/microcks/microcks-uber:latest] (build-9) Creating container for image: quay.io/microcks/microcks-uber:latest
2025-10-08 17:24:37,331 INFO [tc.qua.io/microcks/microcks-uber:latest] (build-9) Container started in PT2.59S
2025-10-08 17:24:37,337 INFO [io.git.mic.qua.dep.DevServicesMicrocksProcessor] (build-9) Loading 'ReceiverAPI-1.0-openapi.yaml' as primary artifact
2025-10-08 17:24:37,568 INFO [io.git.mic.qua.dep.DevServicesMicrocksProcessor] (build-9) Loading 'SenderAPI-1.0-openapi.yaml' as primary artifact
2025-10-08 17:24:37,619 INFO [io.git.mic.qua.dep.DevServicesMicrocksProcessor] (build-9) Microcks container is ready at http://localhost:35299
2025-10-08 17:24:39,146 INFO [io.qua.tes.com.DefaultDockerContainerLauncher] (main)
Executing:
"podman run --name quarkus-integration-test-fjwjp -i --rm -p 56778:56778 -p 8444:8444
--net=14af332156f1842487acba7654ad746feb1099ed2aa07ebe44323b0e4a3d8008
--env QUARKUS_HTTP_PORT=56778
--env QUARKUS_MICROCKS_DEFAULT_HTTP=http://localhost:35299
samples/java-contract-testing-microcks:0.1-SNAPSHOT"
2025-10-08 17:24:42,293 INFO [io.qua.tes.com.DefaultDockerContainerLauncher] (main) Server started on port 56778
2025-10-08 17:24:42,346 INFO [com.ama.sam.sen.SenderContractTest] (main) Endpoint URL for contract test: http://host.containers.internal:56778
2025-10-08 17:24:42,356 INFO [io.qua.tes.com.DefaultDockerContainerLauncher] (main) Closing the container
[ERROR] Tests run: 6, Failures: 1, Errors: 5, Skipped: 0, Time elapsed: 66.65 s <<< FAILURE!
[ERROR] .samples.sender.SenderContractIT.testAllOperationsFromSenderOpenApi -- Time elapsed: 2.421 s <<< FAILURE!
org.opentest4j.AssertionFailedError: Contract test failed for operation: GET /sender ==> expected: <true> but was: <false>
at .samples.sender.SenderContractTest.testAllOperationsFromSenderOpenApi(SenderContractTest.java:150)
[ERROR] .samples.sender.SenderContractIT.testAllOperationsFromSenderOpenApi -- Time elapsed: 0.861 s <<< ERROR!
java.net.ConnectException: Connection refused
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:589)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
at java.base/java.net.Socket.connect(Socket.java:751)
...
at io.github.microcks.testcontainers.MicrocksContainer.testEndpoint(MicrocksContainer.java:519)
2025-10-08 17:24:44,908 INFO [com.git.doc.zer.sha.org.apa.hc.cli.htt.imp.cla.HttpRequestRetryExec] (Thread-739)
Recoverable I/O exception (NoHttpResponseException) caught when processing request to unix://localhost:2375
Exception in multiple threads:
com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"cause":"no such container","message":"no container with ID ... found in database","response":500}
at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247)
at org.testcontainers.utility.JVMHookResourceReaper.prune(JVMHookResourceReaper.java:58)
This indicates that the integration tests failed to connect to the running application within the container
How can I configure Quarkus Testcontainers and Microcks so that integration tests don’t fail with Connection refused when using Podman instead of Docker?
SampleResourceto manage another container or external service during Quarkus integration tests. In this setup, I configured a container for thesample-snapshotimage and retrieved its URL to pass toMicrocksas theendpointUrl, enabling Microcks to call this container during testing. However, this solution currently works only for REST API applications and not for cases that include a REST client.