Как правильно настроить PostgreSQL для интеграционных или unit-тестов?

«Как правильно настроить PostgreSQL для интеграционных или unit-тестов?» — вопрос из категории Тестирование, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для тестов, взаимодействующих с БД, важно использовать изолированное и воспроизводимое окружение. Основные подходы:

1. In-memory база данных (H2 в режиме PostgreSQL)

  • Лучше всего подходит для большинства unit- и интеграционных тестов, не требующих специфичных функций PostgreSQL.
  • Конфигурация в application-test.properties:
    spring.datasource.url=jdbc:h2:mem:testdb;MODE=PostgreSQL;DB_CLOSE_DELAY=-1
    spring.datasource.driver-class-name=org.h2.Driver
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

2. Testcontainers (Docker)

  • Идеально для тестов, которым нужна реальная PostgreSQL со всеми её особенностями.
  • Пример тестового класса:

    @Testcontainers
    @SpringBootTest
    class MyRepositoryTest {
        @Container
        static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");
    
        @DynamicPropertySource
        static void configureProperties(DynamicPropertyRegistry registry) {
            registry.add("spring.datasource.url", postgres::getJdbcUrl);
            registry.add("spring.datasource.username", postgres::getUsername);
            registry.add("spring.datasource.password", postgres::getPassword);
        }
        // ... тесты
    }

3. Локально установленный PostgreSQL (Наименее предпочтительно)

  • Используйте, только если тесты критично зависят от функций, которые не эмулируют H2 или Testcontainers.
  • Недостатки: Зависит от окружения разработчика, сложнее настройка CI/CD.

Важные практики для любых тестов с БД:

  • Используйте транзакции (@Transactional) с откатом после каждого теста.
  • Или очищайте данные в методах, аннотированных @AfterEach / @AfterAll.
  • Настройки БД для тестов должны быть отделены от продакшн-конфигурации (профили Spring).