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.