Как Spring кэширует контекст в тестах и что такое DirtiesContext?
Spring TestContext Framework кэширует ApplicationContext между тестами для повышения производительности. Контекст создаётся один раз и переиспользуется всеми тестами с одинаковой конфигурацией.
Аналогия из жизни: кэширование контекста — как общий рабочий стол в офисе. Пока настройки одинаковые, все используют один стол. Но если кто-то разлил кофе (
@DirtiesContext), стол нужно заменить.
Ключ кэша формируется на основе
- Набора конфигурационных классов / XML-файлов
- Активных профилей (
@ActiveProfiles) - Свойств (
properties) - Наличия
@MockBean/@SpyBean - Других параметров контекста
Если два тестовых класса имеют одинаковый набор параметров, они разделят один и тот же контекст.
DirtiesContext
@DirtiesContext помечает тест, после которого контекст считается «грязным» и должен быть пересоздан. Это необходимо, когда тест изменяет состояние контекста (меняет бин, модифицирует синглтон, изменяет данные в кэше).
Пример
@SpringBootTest
class ContextCachingTest {
@Test
@DirtiesContext
void testThatModifiesContext() {
cacheService.clearAll();
}
// После предыдущего теста контекст будет пересоздан
@Test
void testAfterDirtyContext() {
// работает с чистым контекстом
}
}
Режимы DirtiesContext на уровне класса
Пример
// Пересоздавать контекст после каждого тестового метода
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
// Пересоздать контекст после всего тестового класса
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
// Пересоздать контекст до класса
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
На собеседовании: важно подчеркнуть, что злоупотребление
@DirtiesContextзначительно замедляет тесты, так как пересоздание контекста — дорогостоящая операция. Частая ошибка — ставить@DirtiesContextна каждый тест «для надёжности».