Внедрение зависимостей должно сделать код менее зависимым от контейнера, чем это было бы при традиционной разработке на Java EE. POJO, составляющие ваше приложение, должны быть пригодны к тестированию в JUnit или TestNG вместе с объектами, экземпляры которых были созданы с помощью оператора new, без участия Spring или любого другого контейнера. Можно использовать объекты-имитации (mock objects) (в сочетании с другими полезными методами тестирования) для изолированного тестирования вашего кода. Если следовать рекомендациям по архитектуре Spring, то получаемое в результате чистое многоуровневое и компонентное представление кодовой базы облегчит модульное тестирование. Например, можно проводить тестирование объектов уровня служб с использованием функции-заглушки или объекта-имитации интерфейсов DAO или хранилища, без необходимости доступа к постоянно хранимым данным во время выполнения модульных тестов.
Истинные модульные тесты обычно производятся крайне быстро, поскольку нет необходимости в создании инфраструктуры среды выполнения. Упор на истинные модульные тесты как часть методологии разработки может повысить производительность. Возможно, вам и не пригодится этот раздел главы о тестировании, чтобы писать эффективные модульные тесты для ваших приложений на базе IoC. Однако для определенных сценариев модульного тестирования Spring Framework предоставляет объекты-имитации и вспомогательные классы тестирования, которые в этой главе рассматриваются.
Объект-имитация
Spring имеет ряд пакетов, предназначенных для использования объектов-имитаций:
-
Среда
-
JNDI
-
API-интерфейс сервлетов
-
Модуль Web Reactive в Spring
Окружение
Пакет org.springframework.mock.env содержит имитируемые реализации абстракций Environment и PropertySource (см. разделы "Профили определения бина" и "Абстракция PropertySource"). MockEnvironment и MockPropertySource полезны для разработки внеконтейнерных тестов для кода, который зависит от свойств, специфичных для среды.
JNDI
Пакет org.springframework.mock.jndi содержит частичную реализацию SPI-интерфейса JNDI, которую можно использовать для создания простой среды JNDI для тестовых комплектов или автономных приложений. Если, например, экземпляры DataSource из JDBC привязываются к тем же именам JNDI в тестовом коде, что и в контейнере Java EE, то можно повторно использовать как код приложения, так и конфигурацию в сценариях тестирования без изменений.
org.springframework.mock.jndi официально устарела с версии Spring Framework 5.2, а предпочтение отдается готовым решениям от сторонних разработчиков, таким как
Simple-JNDI.
API-интерфейс сервлетов
Пакет org.springframework.mock.web содержит полный набор объектов-имитаций API-интерфейса сервлетов (Servlet API), которые полезны для тестирования веб-контекстов, контроллеров и фильтров. Эти объекты-имитации предназначены для использования с фреймворком Spring Web MVC и в целом более удобны в пользовании, чем динамические объекты-имитации (например, EasyMock) или альтернативные объекты-имитации Servlet API (например, MockObjects).
org.springframework.mock.web базируются на Servlet API 4.0.
Инфраструктура Spring MVC Test основана на объектах-имитациях Servlet API, что обеспечивает среду интеграционного тестирования для Spring MVC. См. раздел "MockMvc".
Модуль Web Reactive в Spring
Пакет org.springframework.mock.http.server.reactive содержит имитируемые реализации ServerHttpRequest и ServerHttpResponse для использования в приложениях WebFlux. Пакет org.springframework.mock.web.server содержит объект-имитацию ServerWebExchange, который зависит от этих имитируемых объектов-запросов и объектов-ответов.
И MockServerHttpRequest, и MockServerHttpResponse происходят из тех же абстрактных базовых классов, что и специфичные для сервера реализации, и имеют с ними общую логику работы. Например, имитируемый объект-запрос становится незаменяемым после создания, но вы можете использовать метод mutate() из ServerHttpRequest для создания измененного экземпляра.
Для того чтобы имитируемый объект-ответ правильно реализовал контракт на запись и возвращал дескриптор завершения записи (то есть Mono<Void>), он по умолчанию использует Flux с cache().then(), который буферизирует данные и делает их доступными для утверждений в тестах. Приложения могут установить специальную функцию записи (например, для проверки бесконечного потока).
WebTestClient основывается на имитируемых объекте-запросе и объекте-ответе и обеспечивает поддержку тестирования приложений WebFlux без HTTP-сервера. Клиентскую часть также можно использовать для сквозного (end-to-end) тестирования с работающим сервером.
Вспомогательные классы для модульного тестирования
Spring содержит ряд классов, которые могут помочь в модульном тестировании. Они делятся на две категории:
-
Утилиты для тестирования общего назначения
-
Утилиты для тестирования в Spring MVC
Утилиты для тестирования общего назначения
Пакет org.springframework.test.util содержит несколько утилит общего назначения для использования в модульном и интеграционном тестировании.
ReflectionTestUtils – это коллекция служебных методов, основанных на рефлексии. Вы можете использовать эти методы в сценариях тестирования, если нужно изменить значение константы, установить не-public поле, вызвать не-public сеттер или вызвать не-public метод конфигурации или обратного вызова жизненного цикла при тестировании кода приложения в следующих случаях:
-
ORM-фреймворки (такие как JPA и Hibernate), которые допускают
privateилиprotectedдоступ к полям, в отличие отpublicсеттеров свойств в сущности предметной области. -
Поддержка аннотаций Spring (таких как
@Autowired,@Injectи@Resource), которые обеспечивают внедрение зависимостей дляprivateилиprotectedполей, сеттеров и конфигурационных методов. -
Использование аннотаций, таких как
@PostConstructи@PreDestroyдля методов обратного вызова жизненного цикла.
AopTestUtils – это коллекция связанных с АОП служебных методов. Вы можете использовать эти методы для получения ссылки на базовый целевой объект, скрытый за одним или несколькими прокси Spring. Например, если вы сконфигурировали бин в качестве динамического объекта-имитации с помощью такой библиотеки, как EasyMock или Mockito, и этот объект-имитация обернут в прокси Spring, вам может понадобиться прямой доступ к базовому объекту-имитации, чтобы сконфигурировать ожидаемые события для него и выполнить проверку. Для получения информации об основных АОП-утилитах в Spring см. разделы, посвященные AopUtils и AopProxyUtils.
Утилиты для тестирования в Spring MVC
Пакет org.springframework.test.web содержит ModelAndViewAssert, который вы можете использовать в сочетании с JUnit, TestNG или любым другим фреймворком тестирования для модульных тестов, работающих с объектами ModelAndView из Spring MVC.
Controller из Spring MVC в качестве POJO используйте
ModelAndViewAssert в сочетании с
MockHttpServletRequest,
MockHttpSession и т.д. из числа объектов-имитаций Servlet API. Для проведения тщательного интеграционного тестирования классов
Controller из Spring MVC и REST в сочетании с конфигурацией
WebApplicationContext для Spring MVC используйте фреймворк Spring MVC Test Framework.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ