Використання залежностей повинно зробити код менш залежним від контейнера, ніж це було б при традиційній розробці Java EE. POJO, що є вашою програмою, повинні бути придатними для тестування в JUnit або TestNG разом з об'єктами, екземпляри яких були створені за допомогою оператора new, без участі Spring або будь-якого іншого контейнера. Можна використовувати об'єкти-імітації (в поєднанні з іншими корисними методами тестування) для ізольованого тестування твого коду. Якщо дотримуватися рекомендацій з архітектури 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, то можна повторно використовувати як код програми, так і конфігурацію у сценаріях тестування без змін.

Підтримка об'єктів-імітацій JNDI в пакеті 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).

Починаючи зі Spring Framework 5.0, об'єкти-імітації в 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.