Ответ
Основной подход — изоляция тестов от реальных стендов.
1. Использование Testcontainers (рекомендуется для интеграционных тестов):
@Testcontainers
class UserRepositoryIntegrationTest {
@Container
static final PostgreSQLContainer<?> POSTGRES =
new PostgreSQLContainer<>("postgres:13-alpine")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
@BeforeAll
static void setup() {
// Настройка DataSource на основе POSTGRES.getJdbcUrl()
}
}
Преимущества: Тесты запускаются в изолированном Docker-контейнере с точной версией БД.
2. Использование встроенной/легковесной БД (например, H2):
# application-test.properties
spring.datasource.url=jdbc:h2:mem:testdb;MODE=PostgreSQL
spring.datasource.driver-class-name=org.h2.Driver
Важно: Проверять совместимость SQL-диалекта с целевой БД (PostgreSQL, MySQL).
3. Управление схемой через миграции (Flyway/Liquibase):
- Миграционные скрипты гарантируют одинаковую схему на всех окружениях.
- В тестах можно использовать
spring.flyway.locationsдля специфичных тестовых миграций.
4. Мокирование слоя доступа к данным: Используйте Mockito, если тестируете бизнес-логику, а не работу с БД.
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@Test
void shouldReturnUser() {
when(userRepository.findById(1L)).thenReturn(Optional.of(new User()));
// тест сервиса
}
}
Правило: Тесты не должны зависеть от состояния внешних стендов. Версия БД в тестах должна быть либо фиксированной (Testcontainers), либо эмулированной (H2).