Gymterview
middle

Как 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 на каждый тест «для надёжности».