Какой контейнер поднимается при тестировании?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Контейнеры при тестировании в Java
Вопрос о контейнерах при тестировании относится к контейнеризации компонентов и инфраструктуры для тестирования. Это важная тема для разработчиков, работающих с микросервисами и интеграционными тестами.
TestContainers — основной инструмент
TestContainers — это популярная Java библиотека для запуска контейнеризированных зависимостей (БД, очереди, и т.д.) в тестах:
@SpringBootTest
@Testcontainers
public class UserRepositoryTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
.withDatabaseName("testdb")
.withUsername("user")
.withPassword("password");
@Autowired
private UserRepository userRepository;
@Test
void testFindUser() {
User user = new User("test@example.com", "Test User");
userRepository.save(user);
User found = userRepository.findByEmail("test@example.com");
assertThat(found).isNotNull();
}
}
Типы контейнеров для тестирования
1. Database Containers (БД контейнеры)
PostgreSQL
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
.withDatabaseName("mydb")
.withUsername("user")
.withPassword("password")
.withInitScript("init.sql");
MySQL
@Container
static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")
.withDatabaseName("testdb")
.withUsername("root")
.withPassword("password");
MongoDB
@Container
static MongoDBContainer mongo = new MongoDBContainer("mongo:6.0")
.withExposedPorts(27017);
2. Message Queue Containers (очереди сообщений)
RabbitMQ
@Container
static RabbitMQContainer rabbitmq = new RabbitMQContainer("rabbitmq:3.12");
Kafka
@Container
static KafkaContainer kafka = new KafkaContainer(
DockerImageName.parse("confluentinc/cp-kafka:7.5.0")
);
3. Other Service Containers (другие сервисы)
Redis
@Container
static GenericContainer<?> redis = new GenericContainer<>("redis:7")
.withExposedPorts(6379);
Elasticsearch
@Container
static ElasticsearchContainer elasticsearch =
new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.0.0");
Docker API (кастомный контейнер)
@Container
static GenericContainer<?> custom = new GenericContainer<>("myimage:latest")
.withExposedPorts(8080)
.withEnv("ENV_VAR", "value")
.waitingFor(Wait.forHttp("/health").forStatusCode(200));
Spring Boot Integration
С аннотациями @Testcontainers
@SpringBootTest
@Testcontainers
public class IntegrationTest {
@Container
static PostgreSQLContainer<?> db = new PostgreSQLContainer<>();
@BeforeAll
static void setup() {
// db уже запущена
}
}
С DynamicPropertySource
@SpringBootTest
@Testcontainers
public class DatabaseTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>();
@DynamicPropertySource
static void registerDynamicProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
}
Примеры полных тестов
Тест репозитория с Testcontainers
@SpringBootTest
@Testcontainers
public class OrderRepositoryTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>()
.withDatabaseName("testdb");
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Autowired
private OrderRepository orderRepository;
@Test
void testSaveAndFind() {
Order order = new Order("ORD-001", BigDecimal.valueOf(100));
Order saved = orderRepository.save(order);
Optional<Order> found = orderRepository.findById(saved.getId());
assertThat(found).isPresent();
assertThat(found.get().getNumber()).isEqualTo("ORD-001");
}
}
Тест с Kafka
@SpringBootTest
@Testcontainers
public class KafkaIntegrationTest {
@Container
static KafkaContainer kafka = new KafkaContainer(
DockerImageName.parse("confluentinc/cp-kafka:7.5.0")
);
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("spring.kafka.bootstrap-servers", kafka::getBootstrapServers);
}
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private KafkaListener listener; // или @KafkaListener тест
@Test
void testProduceConsume() throws Exception {
// Отправить сообщение
kafkaTemplate.send("test-topic", "test-key", "test-message");
// Проверить что слушатель получил
// ...
}
}
Docker Compose для сложной инфраструктуры
Для стека из нескольких сервисов можно использовать Docker Compose:
@SpringBootTest
@Testcontainers
public class DockerComposeTest {
@Container
static DockerComposeContainer<?> compose =
new DockerComposeContainer<>(new File("docker-compose.test.yml"))
.withService("postgres")
.withService("redis")
.withService("kafka");
@DynamicPropertySource
static void properties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url",
() -> "jdbc:postgresql://" +
compose.getServiceHost("postgres", 5432) + ":" +
compose.getServicePort("postgres", 5432) + "/testdb");
}
}
Best Practices
-
Используй @Container для static полей — переиспользуется между тестами
@Container static PostgreSQLContainer<?> db = new PostgreSQLContainer<>(); -
Для isolate тестов используй instance контейнеры
@Container PostgreSQLContainer<?> db = new PostgreSQLContainer<>(); // для каждого теста -
Добавь health checks
.waitingFor(Wait.forLogMessage(".*ready to accept connections.*", 1)) .waitingFor(Wait.forHttp("/health").forStatusCode(200)) -
Минимизируй время запуска
- Переиспользуй контейнеры (static)
- Используй Ryuk для очистки
- Настрой Docker оптимально
-
Кэшируй образы
docker pull postgres:15 # Testcontainers будет переиспользовать
Gradle/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>
Альтернативы
- H2 In-Memory DB — для простых тестов
- Embedded PostgreSQL — postgres-embedded
- Mock Servers — WireMock, MockServer
- Docker для CI/CD — GitHub Actions, GitLab CI
Итог: при тестировании Java приложений поднимаются контейнеры Testcontainers — PostgreSQL, MySQL, MongoDB, Redis, Kafka, RabbitMQ и другие. Это позволяет писать реальные интеграционные тесты без необходимости вручную управлять БД и сервисами.