Spring Boot: тестирование, автоконфигурация и нарезка

Дополнительная автоконфигурация и нарезка

Каждый срез содержит одну или несколько аннотаций @AutoConfigure…, которые, в частности, определяют автоконфигурации, которые должны быть включены как часть среза. Дополнительные автоконфигурации можно добавить, создав пользовательскую аннотацию @AutoConfigure… или просто добавив @ImportAutoConfiguration в тест, как показано в следующем примере:

@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
class ExampleJdbcTests {

}

Убедитесь, что вы не используете обычную аннотацию @Import для импорта автоконфигураций, так как они обрабатываются Spring Boot определенным образом.

Конфигурация пользователя и нарезка

Если вы структурируете свой код разумным образом, ваш класс @SpringBootApplication по умолчанию используется в качестве конфигурации ваших тестов.

Тогда становится важным не засорять основной класс приложения настройками конфигурации, специфичными для конкретной области его функциональных возможностей.

Предположим, что вы используете Spring Batch, и вы полагаетесь на автоконфигурацию для него. Вы можете определить свое @SpringBootApplication следующим образом:

@SpringBootApplication
@EnableBatchProcessing
public class SampleApplication { ... }

Поскольку этот класс является исходной конфигурацией для теста, любой тест среза на самом деле пытается запустить Spring Batch, что, безусловно, не то, что вы хотите сделать. Рекомендуемый подход состоит в том, чтобы переместить эту специфичную для области конфигурацию в отдельный класс @Configuration на том же уровне, что и ваше приложение, как показано в следующем примере:

@Configuration(proxyBeanMethods = false)
@EnableBatchProcessing
public class BatchConfiguration { ... }

В зависимости от сложности вашего приложения у вас может быть один класс @Configuration для ваших настроек или один класс на область домена. Последний подход позволяет включить его в одном из ваших тестов, если необходимо, с аннотацией @Import.

Тестовые срезы исключают классы @Configuration из сканирования. Например, для @WebMvcTest следующая конфигурация не будет включать данный компонент WebMvcConfigurer в контекст приложения, загруженный тестовым срезом:

@Configuration
public class WebConfiguration {
    @Bean
    public WebMvcConfigurer testConfigurer() {
        return new WebMvcConfigurer() {
            ...
        };
    }
}

Однако приведенная ниже конфигурация приведет к загрузке пользовательского WebMvcConfigurer из тестового среза.

@Component
public class TestWebMvcConfigurer implements WebMvcConfigurer {
    ...
}

Еще одним источником путаницы является сканирование пути к классам. Предположим, что пока вы разумно структурировали свой код, вам нужно отсканировать дополнительный пакет. Ваше приложение может напоминать следующий код:

@SpringBootApplication
@ComponentScan({ "com.example.app", "org.acme.another" })
public class SampleApplication { ... }

Это эффективно переопределяет директиву сканирования компонентов по умолчанию с побочным эффектом сканирования этих двух пакетов независимо от выбранного среза. Например, @DataJpaTest, кажется, внезапно сканирует компоненты и пользовательские конфигурации вашего приложения. Опять же, перемещение пользовательской директивы в отдельный класс является хорошим способом решения этой проблемы.

Если это не вариант для вас, вы можете создать @SpringBootConfiguration где-нибудь в иерархии вашего теста, чтобы использовать его вместо этого. Кроме того, вы можете указать источник для вашего теста, который отключает поведение поиска по умолчанию.

Использование Spock для тестирования приложений Spring Boot

Если вы хотите использовать Spock для тестирования приложения Spring Boot, вы должны добавить зависимость от модуля Spock spock-spring в сборку вашего приложения. spock-spring интегрирует тестовую среду Spring в Spock. Рекомендуется использовать Spock 1.2 или более позднюю версию, чтобы воспользоваться рядом улучшений интеграции Spock Spring Framework и Spring Boot.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки