Integration Testing Java with Docker: A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Integration Testing of Java Applications with Docker



Modern Java development is unthinkable without quality testing. However, unit tests are often unable to identify problems that arise when components interact with real databases, message queues, or external APIs. This is where integration testing comes to the rescue, and Docker makes this process simple, reproducible, and isolated. In this article, we will explore how to effectively use Docker for integration testing of Java applications using the Testcontainers library and Docker Compose.



Why Docker Changes the Game in Integration Testing?



The traditional approach to integration testing often requires installing and configuring all dependencies (databases, message brokers) on the developer's local machine or on the CI server. This leads to a number of problems:



  • Environment instability: Different DBMS versions, port conflicts, differences between the development and production environments.
  • Complexity of CI/CD setup: The need to manually install and configure services in the pipeline.
  • Data pollution: Test data can remain in the local database, affecting subsequent runs.
  • Parallelization: Running tests simultaneously on one machine can lead to conflicts.


Docker solves these problems by providing lightweight, isolated, and ephemeral containers. Each test (or set of tests) can start its own instance of PostgreSQL, Redis, or Kafka, and after the test completes, destroy it. This guarantees clean and repeatable results.



Project Setup: Testcontainers vs Docker Compose



There are two main approaches to integrating Docker into Java tests. Let's look at both.



1. Testcontainers: A Library for Managing Containers from Code



Testcontainers is a Java library that allows you to manage the lifecycle of Docker containers directly from your tests. It is the de facto standard for integration testing in the Spring Boot ecosystem and beyond.



Advantages:

  • Programmatic control: containers are started and stopped automatically.
  • Support for popular services "out of the box" (GenericContainer, PostgreSQLContainer, KafkaContainer, etc.).
  • Automatic selection of free ports (avoids conflicts).
  • Ideal for unit integration tests.


Example: Testing a REST Controller with PostgreSQL



Add the dependency to your pom.xml (Maven):



<dependency>    <groupId>org.testcontainers</groupId>    <artifactId>testcontainers</artifactId>    <version>1.19.3</version>    <scope>test</scope></dependency><dependency>    <groupId>org.testcontainers</groupId>    <artifactId>postgresql</artifactId>    <version>1.19.3</version>    <scope>test</scope></dependency>


Now let's write a test for a Spring Boot application that works with PostgreSQL:



import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.boot.test.web.client.TestRestTemplate;import org.springframework.http.ResponseEntity;import org.testcontainers.containers.PostgreSQLContainer;import org.testcontainers.junit.jupiter.Container;import org.testcontainers.junit.jupiter.Testcontainers;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnviron

Blogs

Book Recommendations