Сообщения

Сообщения за октябрь, 2020

Интеграционное тестирование в Spring: TestContext Framework, тестирование бинов области действия запроса и сеанса

Изображение
Spring поддерживает bean-компоненты с областью действия запроса и сеанса (request- и session-scoped beans) еще с ранних релизов, и вы можете протестировать bean-компоненты с областью действия запроса и сеанса, выполнив следующие действия: Убедитесь, что WebApplicationContext загружен для вашего теста, аннотируя тестовый класс с помощью @WebAppConfiguration. Внедрите фиктивный (mock) запрос или сеанс в свой тестовый экземпляр и при необходимости подготовьте тестовое приспособление. Вызовите свой веб-компонент, полученный из настроенного контекста WebApplicationContext (с внедрением зависимостей). Выполняйте утверждения против моков. Следующий фрагмент кода показывает конфигурацию XML для варианта использования входа (login). Обратите внимание, что bean-компонент userService зависит от bean-компонента loginAction в области запроса. Кроме того, LoginAction создается с помощью выражений SpEL, которые извлекают имя пользователя и пароль из текущего HTTP-запроса. В нашем тесте мы хоти

Интеграционное тестирование в Spring: TestContext Framework, внедрение зависимостей тестовых приспособлений

Изображение
Когда вы используете DependencyInjectionTestExecutionListener (который настроен по умолчанию), зависимости ваших тестовых экземпляров вводятся из bean-компонентов в контексте приложения, который вы настроили с помощью @ContextConfiguration или связанных аннотаций. Вы можете использовать внедрение сеттера, внедрение поля или и то, и другое, в зависимости от того, какие аннотации вы выбираете и размещаете ли вы их в методах или полях установщика. Если вы используете JUnit Jupiter, вы также можете дополнительно использовать внедрение конструктора (внедрение зависимостей с помощью SpringExtension). Для обеспечения согласованности с поддержкой Spring на основе аннотаций вы также можете использовать аннотацию Spring @Autowired или аннотацию @Inject из JSR-330 для внедрения полей и установщиков. Для фреймворков тестирования, отличных от JUnit Jupiter, TestContext framework не участвует в создании экземпляра тестового класса. Таким образом, использование @Autowired или @Inject для конструктор

Интеграционное тестирование в Spring: TestContext Framework, иерархии контекстов

Изображение
При написании интеграционных тестов, основанных на загруженном Spring ApplicationContext, часто бывает достаточно тестирования в одном контексте. Однако бывают случаи, когда полезно или даже необходимо протестировать иерархию экземпляров ApplicationContext. Например, если вы разрабатываете веб-приложение Spring MVC, у вас обычно есть корневой WebApplicationContext, загруженный Spring ContextLoaderListener, и дочерний WebApplicationContext, загруженный Spring DispatcherServlet. Это приводит к иерархии родительско-дочернего контекста, в которой общие компоненты и конфигурация инфраструктуры объявляются в корневом контексте и используются в дочернем контексте веб-компонентами. Другой вариант использования можно найти в приложениях Spring Batch, где у вас часто есть родительский контекст, который обеспечивает конфигурацию для разделяемой пакетной инфраструктуры, и дочерний контекст для конфигурации определенного пакетного задания. Вы можете писать интеграционные тесты, использующие контек

Интеграционное тестирование в Spring: TestContext Framework, кэширование контекста

Изображение
Как только TestContext framework загружает ApplicationContext (или WebApplicationContext) для теста, этот контекст кэшируется и повторно используется для всех последующих тестов, которые объявляют ту же уникальную конфигурацию контекста в одном и том же наборе тестов. Чтобы понять, как работает кэширование, важно понимать, что имеется в виду под "уникальным" и "набором тестов". ApplicationContext можно однозначно идентифицировать по комбинации параметров конфигурации, которые используются для его загрузки. Следовательно, уникальная комбинация параметров конфигурации используется для генерации ключа, под которым кэшируется контекст. TestContext framework использует следующие параметры конфигурации для создания ключа кэша контекста: locations (из @ContextConfiguration) classes (из @ContextConfiguration) contextInitializerClasses (из @ContextConfiguration) contextCustomizers (из ContextCustomizerFactory) - это включает методы @DynamicPropertySource, а также разли

Интеграционное тестирование в Spring: TestContext Framework, загрузка WebApplicationContext

Изображение
Чтобы проинструктировать TestContext framework загружать WebApplicationContext вместо стандартного ApplicationContext, вы можете аннотировать соответствующий тестовый класс с помощью @WebAppConfiguration. Присутствие @WebAppConfiguration в вашем тестовом классе указывает TestContext framework (TCF), что WebApplicationContext (WAC) должен быть загружен для ваших интеграционных тестов. В фоновом режиме TCF гарантирует, что MockServletContext создан и передан в WAC вашего теста. По умолчанию базовый путь к ресурсу для вашего MockServletContext установлен на src/main/webapp. Это интерпретируется как путь относительно корня вашей JVM (обычно путь к вашему проекту). Если вы знакомы со структурой каталогов веб-приложения в проекте Maven, вы знаете, что src/main/webapp - это расположение по умолчанию для корня вашего WAR. Если вам нужно переопределить это значение по умолчанию, вы можете указать альтернативный путь к аннотации @WebAppConfiguration (например, @WebAppConfiguration("src/tes

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста с динамическими источниками свойств

Изображение
Начиная с Spring Framework 5.2.5, TestContext framework обеспечивает поддержку динамических свойств через аннотацию @DynamicPropertySource. Эту аннотацию можно использовать в интеграционных тестах, которым необходимо добавить свойства с динамическими значениями в набор PropertySources в Environment для ApplicationContext, загруженного для интеграционного теста. Аннотация @DynamicPropertySource и ее поддерживающая инфраструктура изначально были разработаны для того, чтобы свойства из тестов, основанных на Testcontainers, были легко доступны для интеграционных тестов Spring. Однако эту функцию также можно использовать с любой формой внешнего ресурса, жизненный цикл которого поддерживается за пределами ApplicationContext теста. В отличие от аннотации @TestPropertySource, которая применяется на уровне класса, @DynamicPropertySource необходимо применять к статическому методу, который принимает один аргумент DynamicPropertyRegistry, который используется для добавления пар ключ-значение в с

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста с источниками тестовых свойств

Изображение
Spring Framework имеет первоклассную поддержку понятия среды с иерархией источников свойств, и вы можете настроить интеграционные тесты с источниками свойств для конкретных тестов. В отличие от аннотации @PropertySource, используемой в классах @Configuration, вы можете объявить аннотацию @TestPropertySource в тестовом классе для объявления местоположений ресурсов для файлов тестовых свойств или встроенных свойств. Эти источники тестовых свойств добавляются к набору PropertySources в Environment для ApplicationContext, загруженного для аннотированного интеграционного теста. Вы можете использовать @TestPropertySource с любой реализацией SPI SmartContextLoader, но @TestPropertySource не поддерживается с реализациями более старого SPI ContextLoader. Реализации SmartContextLoader получают доступ к объединенным значениям источника свойств теста через методы getPropertySourceLocations() и getPropertySourceProperties() в MergedContextConfiguration. Объявление источников тестовых свойств Вы

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста с профилями среды

Изображение
Spring Framework имеет первоклассную поддержку понятий сред и профилей (также известных как "профили определения bean-компонентов"), а интеграционные тесты можно настроить для активации определенных профилей определения bean-компонентов для различных сценариев тестирования. Это достигается путем аннотирования тестового класса аннотацией @ActiveProfiles и предоставления списка профилей, которые должны быть активированы при загрузке ApplicationContext для теста. Вы можете использовать @ActiveProfiles с любой реализацией SPI SmartContextLoader, но @ActiveProfiles не поддерживается с реализациями более старого SPI ContextLoader. Рассмотрим два примера с конфигурацией XML и классами @Configuration: <!-- app-config.xml --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springfram

Интеграционное тестирование в Spring: TestContext Framework, наследование конфигурации контекста

Изображение
@ContextConfiguration поддерживает логические атрибуты inheritLocations и inheritInitializers, которые указывают, должны ли наследоваться местоположения ресурсов или классы компонентов и инициализаторы контекста, объявленные суперклассами. Значение по умолчанию для обоих флагов - true. Это означает, что тестовый класс наследует расположение ресурсов или классы компонентов, а также инициализаторы контекста, объявленные любыми суперклассами. В частности, местоположения ресурсов или классы компонентов для тестового класса добавляются к списку местоположений ресурсов или аннотированных классов, объявленных суперклассами. Точно так же инициализаторы для данного тестового класса добавляются к набору инициализаторов, определенных тестовыми суперклассами. Таким образом, подклассы имеют возможность расширять расположение ресурсов, классы компонентов или инициализаторы контекста. Если для атрибута inheritLocations или inheritInitializers в @ContextConfiguration установлено значение false, место

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста с инициализаторами контекста

Изображение
Чтобы настроить ApplicationContext для ваших тестов с помощью инициализаторов контекста, аннотируйте тестовый класс с помощью @ContextConfiguration и настройте атрибут initializers с помощью массива, который содержит ссылки на классы, реализующие ApplicationContextInitializer. Объявленные инициализаторы контекста затем используются для инициализации ConfigurableApplicationContext, который загружается для ваших тестов. Обратите внимание, что конкретный тип ConfigurableApplicationContext, поддерживаемый каждым объявленным инициализатором, должен быть совместим с типом ApplicationContext, созданным используемым SmartContextLoader (обычно это GenericApplicationContext). Кроме того, порядок, в котором вызываются инициализаторы, зависит от того, реализуют ли они интерфейс Spring Ordered или аннотированы аннотацией Spring @Order или стандартной аннотацией @Priority. В следующем примере показано, как использовать инициализаторы: @ExtendWith(SpringExtension.class) // ApplicationContext буде

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста - смешивание XML, скриптов Groovy и классов компонентов

Изображение
Иногда может быть желательно смешивать файлы конфигурации XML, сценарии Groovy и классы компонентов (обычно классы @Configuration) для настройки ApplicationContext для ваших тестов. Например, если вы используете конфигурацию XML в производственной среде, вы можете решить, что хотите использовать классы @Configuration для настройки определенных компонентов, управляемых Spring, для ваших тестов, или наоборот. Кроме того, некоторые сторонние платформы (например, Spring Boot) предоставляют первоклассную поддержку для одновременной загрузки ApplicationContext из разных типов ресурсов (например, файлов конфигурации XML, сценариев Groovy и классов @Configuration). Spring Framework исторически не поддерживала это для стандартных развертываний. Следовательно, большинство реализаций SmartContextLoader, которые Spring Framework предоставляет в модуле spring-test, поддерживают только один тип ресурса для каждого контекста теста. Однако это не означает, что вы не можете использовать оба. Единствен

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста с классами компонентов

Изображение
Чтобы загрузить ApplicationContext для ваших тестов с помощью классов компонентов, вы можете аннотировать свой тестовый класс с помощью @ContextConfiguration и настроить атрибут классов с помощью массива, содержащего ссылки на классы компонентов. В следующем примере показано, как это сделать: @ExtendWith(SpringExtension.class) // ApplicationContext будет загружен из // AppConfig и TestConfig @ContextConfiguration(classes = {AppConfig.class, TestConfig.class}) class MyTest { // тело класса... } Компонентные классы Термин "класс компонента" может относиться к любому из следующего: Класс, помеченный @Configuration. Компонент (то есть класс с аннотациями @Component, @Service, @Repository или другими стереотипными аннотациями). Класс, совместимый с JSR-330, снабженный аннотациями javax.inject. Любой класс, содержащий @Bean-методы. Любой другой класс, который предназначен для регистрации в качестве компонента Spring (т.е. Bean-компонента Spring в ApplicationCont

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста с помощью скриптов Groovy

Изображение
Чтобы загрузить ApplicationContext для ваших тестов с помощью скриптов Groovy, которые используют Groovy Bean Definition DSL, вы можете аннотировать свой тестовый класс с помощью @ContextConfiguration и настроить атрибут местоположений или значения с помощью массива, который содержит местоположения ресурсов скриптов Groovy. Семантика поиска ресурсов для сценариев Groovy такая же, как и для файлов конфигурации XML. Включение поддержки скриптов Groovy Поддержка использования скриптов Groovy для загрузки ApplicationContext в Spring TestContext Framework включается автоматически, если Groovy находится в пути к классам. В следующем примере показано, как указать файлы конфигурации Groovy: @ExtendWith(SpringExtension.class) // ApplicationContext будет загружен // из "/AppConfig.groovy" и // "/TestConfig.groovy" в корне пути к классам @ContextConfiguration({"/AppConfig.groovy", "/TestConfig.Groovy"}) class MyTest { // тело класса... } Есл

Интеграционное тестирование в Spring: TestContext Framework, конфигурация контекста с ресурсами XML

Изображение
Чтобы загрузить ApplicationContext для ваших тестов с помощью файлов конфигурации XML, аннотируйте свой тестовый класс с помощью @ContextConfiguration и настройте атрибут location с помощью массива, который содержит местоположения ресурсов метаданных конфигурации XML. Простой или относительный путь (например, context.xml) обрабатывается как ресурс пути к классам, относящийся к пакету, в котором определен тестовый класс. Путь, начинающийся с косой черты, рассматривается как абсолютное расположение пути к классам (например, /org/example/config.xml). Путь, представляющий URL-адрес ресурса (т.е. путь с префиксом classpath:, file:, http: и т.д.), используется как есть. @ExtendWith(SpringExtension.class) // ApplicationContext будет загружен из "/app-config.xml" и // "/test-config.xml" в корне пути к классам @ContextConfiguration(locations={"/app-config.xml", "/test-config.xml"}) class MyTest { // тело класса... } @ContextConfiguration подде

Интеграционное тестирование в Spring: TestContext Framework, управление контекстом

Изображение
Каждый TestContext обеспечивает управление контекстом и поддержку кеширования для тестового экземпляра, за который он отвечает. Экземпляры тестов не получают автоматически доступ к настроенному ApplicationContext. Однако, если тестовый класс реализует интерфейс ApplicationContextAware, ссылка на ApplicationContext предоставляется экземпляру теста. Обратите внимание, что AbstractJUnit4SpringContextTests и AbstractTestNGSpringContextTests реализуют ApplicationContextAware и, следовательно, автоматически предоставляют доступ к ApplicationContext. @Autowired ApplicationContext В качестве альтернативы реализации интерфейса ApplicationContextAware вы можете внедрить контекст приложения для своего тестового класса с помощью аннотации @Autowired либо в поле, либо в методе установки, как показано в следующем примере: @SpringJUnitConfig class MyTest { @Autowired ApplicationContext applicationContext; // тело класса... } Точно так же, если ваш тест настроен на загрузку Web

Интеграционное тестирование в Spring: TestContext Framework, события выполнения теста

Изображение
EventPublishingTestExecutionListener, представленный в Spring Framework 5.2, предлагает альтернативный подход к реализации настраиваемого TestExecutionListener. Компоненты в ApplicationContext теста могут прослушивать следующие события, опубликованные EventPublishingTestExecutionListener, каждое из которых соответствует методу в TestExecutionListener API. BeforeTestClassEvent PrepareTestInstanceEvent BeforeTestMethodEvent BeforeTestExecutionEvent AfterTestExecutionEvent AfterTestMethodEvent AfterTestClassEvent Эти события публикуются, только если ApplicationContext уже загружен. Эти события могут использоваться по разным причинам, например, для сброса фиктивных компонентов или для отслеживания выполнения теста. Одним из преимуществ использования событий выполнения теста вместо реализации настраиваемого TestExecutionListener является то, что события выполнения теста могут потребляться любым компонентом Spring, зарегистрированным в тестовом ApplicationContext, и такие компонен

Интеграционное тестирование в Spring: TestContext Framework, конфигурация TestExecutionListener

Изображение
Spring предоставляет следующие реализации TestExecutionListener, которые регистрируются по умолчанию, в следующем порядке: ServletTestExecutionListener: настраивает Servlet API моки для WebApplicationContext. DirtiesContextBeforeModesTestExecutionListener: обрабатывает аннотацию @DirtiesContext для режимов "до" (“before”). DependencyInjectionTestExecutionListener: обеспечивает внедрение зависимостей для тестового экземпляра. DirtiesContextTestExecutionListener: обрабатывает аннотацию @DirtiesContext для режимов "после" (“after”). TransactionalTestExecutionListener: обеспечивает выполнение транзакционного теста с семантикой отката по умолчанию. SqlScriptsTestExecutionListener: запускает сценарии SQL, настроенные с помощью аннотации @Sql. EventPublishingTestExecutionListener: публикует события выполнения теста в ApplicationContext теста. Регистрация реализаций TestExecutionListener Вы можете зарегистрировать реализации TestExecutionListener для тестового кл