Внедрение зависимостей должно сделать код менее зависимым от контейнера, чем это было бы при традиционной разработке на 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.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ