«1. Обзор

В этом кратком руководстве мы узнаем об аннотации @DirtiesContext. Мы также покажем стандартный способ использования аннотации для тестирования.

2. @DirtiesContext

@DirtiesContext — это аннотация для тестирования Spring. Это указывает на то, что связанный тест или класс изменяет ApplicationContext. Он сообщает среде тестирования закрыть и воссоздать контекст для последующих тестов.

Мы можем аннотировать тестовый метод или весь класс. Установив MethodMode или ClassMode, мы можем контролировать, когда Spring помечает контекст для закрытия.

Если мы поместим @DirtiesContext в класс, аннотация будет применяться ко всем методам в классе с заданным ClassMode.

3. Тестирование без очистки контекста Spring

Допустим, у нас есть пользователь:

public class User {
    String firstName;
    String lastName;
}

У нас также есть очень простой UserCache:

@Component
public class UserCache {

    @Getter
    private Set<String> userList = new HashSet<>();

    public boolean addUser(String user) {
        return userList.add(user);
    }

    public void printUserList(String message) {
        System.out.println(message + ": " + userList);
    }

}

Мы создаем интеграционный тест для загрузки и протестировать полное приложение:

@TestMethodOrder(OrderAnnotation.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = SpringDataRestApplication.class)
class DirtiesContextIntegrationTest {

    @Autowired
    protected UserCache userCache;
    
    ...
}

Первый метод, addJaneDoeAndPrintCache, добавляет запись в кеш:

@Test
@Order(1)
void addJaneDoeAndPrintCache() {
    userCache.addUser("Jane Doe");
    userCache.printUserList("addJaneDoeAndPrintCache");
}

После добавления пользователя в кеш он печатает содержимое кеша:

addJaneDoeAndPrintCache: [Jane Doe]

~ ~~ Затем printCache снова печатает пользовательский кеш:

@Test
@Order(2)
void printCache() {
    userCache.printUserList("printCache");
}

Он содержит имя, добавленное в предыдущем тесте:

printCache: [Jane Doe]

Допустим, более поздний тест полагался на пустой кеш для некоторых утверждений. Ранее вставленные имена могут вызвать нежелательное поведение.

4. Использование @DirtiesContext

Теперь мы покажем @DirtiesContext с методом по умолчанию, AFTER_METHOD. Это означает, что Spring пометит контекст для закрытия после завершения соответствующего метода тестирования.

Чтобы изолировать изменения в тесте, мы добавляем @DirtiesContext. Давайте посмотрим, как это работает.

Тестовый метод addJohnDoeAndPrintCache добавляет пользователя в кеш. Мы также добавили аннотацию @DirtiesContext, в которой говорится, что контекст должен закрыться в конце тестового метода:

@DirtiesContext(methodMode = MethodMode.AFTER_METHOD)
@Test
@Order(3)
void addJohnDoeAndPrintCache() {
    userCache.addUser("John Doe");
    userCache.printUserList("addJohnDoeAndPrintCache");
}

Теперь вывод:

addJohnDoeAndPrintCache: [John Doe, Jane Doe]

Наконец, printCacheAgain снова печатает кэш: ~ ~~

@Test
@Order(4)
void printCacheAgain() {
    userCache.printUserList("printCacheAgain");
}

Запустив полный тестовый класс, мы видим перезагрузку контекста Spring между addJohnDoeAndPrintCache и printCacheAgain. Таким образом, кеш повторно инициализируется, а вывод пуст:

printCacheAgain: []

5. Другие поддерживаемые этапы тестирования

В приведенном выше примере показан этап после текущего метода тестирования. Давайте сделаем краткий обзор фаз:

5.1. Уровень класса

Параметры ClassMode для тестового класса определяют, когда контекст сбрасывается:

    BEFORE_CLASS: Перед текущим тестовым классом BEFORE_EACH_TEST_METHOD: Перед каждым тестовым методом в текущем тестовом классе AFTER_EACH_TEST_METHOD: После каждого тестового метода в текущем тестовом классе AFTER_CLASS: после текущего тестового класса

5.2. Уровень метода

Параметры MethodMode для отдельного метода определяют, когда контекст сбрасывается:

    BEFORE_METHOD: до текущего метода тестирования AFTER_METHOD: после текущего метода тестирования

6. Заключение

В этой статье мы представил тестовую аннотацию @DirtiesContext.

Как всегда, код примера доступен на GitHub.