Какие spring boot аннотации позволят проверить протестировать различные части вашего приложения
Нам часто нужно проверять входящие параметры: если данных меньше, их легче обрабатывать, но когда данных больше, это будет более проблематично, а когда данные не будут обработаны должным образом, код будет повторяться. В это время Spring Boot необходимо проверить параметры.
В настоящее время вам необходимо использовать проверку для проверки данных.
Использовать валидацию в Spring Boot
Существует следующий фрагмент кода:
Вы можете видеть, что запрос поступает в Book, класс Book выглядит следующим образом:
Теперь вам нужно проверить атрибуты в книге, если вы используете, если еще, чтобы проверить, это будет очень хлопотно. В настоящее время вы можете добавить аннотацию Validation к свойствам в Book следующим образом:
Аннотация NotBlank ссылается на значение атрибута, которое не может быть пустым.
Затем необходимо добавить аннотацию @Valid к полю метода в контроллере, который необходимо проверить, что указывает на необходимость проверки этого параметра, следующим образом:
В это время, если bookName и bookAuthor пусты, появится код ответа 400.
Spring Boot возвращается в это время:
Пользовательская информация проверки и обработки ошибок
Параметр типа BindingResult или Errors можно передать в методе Spring Boot Controller,Стоит отметить, что положение этого параметра должно быть @Valid Параметр, измененный аннотацией, следует (то есть Следующий параметр, измененный @Valid ) Сзади, если впереди, появится следующая ошибка, если не дальше, то этот параметр не будет работать。
Следующий код показывает, как выполнить пользовательскую обработку ошибок:
Результат:
Ошибка здесь заключается в простой печати.
Это будет более хлопотно, когда есть больше Бинов, которые необходимо проверить, поэтому вы можете использовать механизм обработки исключений Spring Boot в это время.
Обработка исключений Spring Boot + проверка бинов
В настоящее время метод в контроллере не нуждается в параметрах типа BindingResult или Errors.
Некоторые часто используемые аннотации валидации
аннотирование | эффект |
---|---|
@NotNull | Значение не может быть пустым |
@Null | Значение должно быть пустым |
@Pattern(regex=) | Строка должна соответствовать регулярному выражению |
@Size(min, max) | Количество заданных элементов должно быть от мин до макс. |
@CreditCardNumber(ignoreNonDigitCharacters=) | Строка должна быть номером кредитной карты, проверенной в соответствии со стандартами США. |
Строка должна быть адресом электронной почты | |
@Length(min, max) | Проверьте длину строки |
@NotBlank | Строка не может быть пустой |
@NotEmpty | Строка не может быть нулевой, коллекция должна содержать элементы |
@Range(min, max) | Число должно быть больше минимального и меньше максимального |
@SafeHtml | Строка должна быть безопасной HTML |
@URL | Строка должна быть действительным URL |
@AssertFalse | Значение должно быть ложным |
@AssertTrue | Значение должно быть истинным |
@DecimalMax(value=, inclusive=) | Значение должно быть меньше или равно (включительно = true) / меньше (включительно = false). Значение, указанное атрибутом, также может быть аннотировано в атрибуте типа строки. |
@DecimalMin(value=, inclusive=) | Значение должно быть больше или равно (включительно = true) / меньше (включительно = false). Значение, указанное атрибутом, также может быть аннотировано в атрибуте типа строки. |
@Digist(integer=,fraction=) | Проверка цифрового формата. целое число задает максимальную длину целочисленной части, дробь задает максимальную длину дробной части |
@Future | Время должно быть в будущем |
@Past | Событие должно быть в прошлом |
@Max(value=) | Значение должно быть меньше или равно значению, указанному в значении. Не может быть аннотировано для атрибутов строкового типа. |
@Min(value=) | Значение должно быть меньше или равно значению, указанному в значении. Не может быть аннотировано для атрибутов строкового типа. |
Интеллектуальная рекомендация
Gensim Skip-Gram модель для Word2Vec
Вступление Генизм - это библиотека Python с открытым исходным кодом, которая используется для легко эффективно извлечь семантические темы в документах. Он используется для обработки оригинального, нес.
Встраиваем VSCode в OpenCV IDE (C ++, window10 1803)
Каталог статей вступление окружение шаг 1. Конфигурация Visual Studio Code 2. Конфигурация OpenCV 3. Конфигурация MinGw 4. Конфигурация cmake 5. Конфигурация проекта 6. Ссылка на ссылку В конце концов.
Интеграция и инструменты fastDFS + spring + maven
После завершения установки его нужно интегрировать в проект. 1. Поместите файл в папку config. 1.1 Содержание файла tracker_server = 192.168.1.202: 22122 - адрес сервера отслеживания, номер порта по у.
Основы Linux
Пользователи Linux делятся на два типа: Пользователь суперадминистратора: root, хранится в каталоге / root Обычные пользователи: хранятся в каталоге / home Каталог Linux /: [*] Корневой каталог. Как п.
С появлением Spring Boot появилась масса возможностей для тестирования различных слоёв. Итак, у нас есть приложение c backend и UI. UI использует backend, а backend содержит следующий код:
Данный код содержит REST контроллер, который получает и изменяет объекты Person, используя PersonRepository. Этот контроллер возвращает/принимает JSON и он будет использовать UI приложения с помощью AJAX.
В нашем коде не предусмотрено никакого Spring Security и методы должны возвращаться вне зависимости от аутентификации и авторизации.
Что же мы хотим протестировать и для чего?
Есть несколько кейсов, где тесты действительно нужны, итак: 1. Контроллер отправляет и принимает PersonDto, а работает с доменными сущностями Person. Эти преобразования осуществляются с помощью статических методов PersonDto и должны быть покрыты тестами просто по правилам приличия. 2. Конкретный PersonDto преобразуется в JSON в методе получения и используется на UI. Нам хочется зафиксировать формат JSON, который будет возвращаться, чтобы при исправлениях в backend приложения мы не изменили этот формат и не поломали UI. 3. JSON с данными о Person также отправляется c UI на backend, плюс хочется также проверить, что отправляемые сейчас данные будут корректно приниматься backend-ом. 4. Контроллер по идее возвращает 200 OK всегда при существующих данных, поэтому хочется зафиксировать данное поведение при каждом запросе.
Поехали?
Для тестирования статических методов, никакого SpringBoot и не надо!
Зафиксируем теперь формат JSON, в который превращается DTO. Вот здесь и помогает SpringBoot — в данном случае аннотация @JsonTest инициализирует контекст и включает Jackson в той конфигурации, что используется в проекте.
А вот теперь пришла пора проверить, как десериализуется JSON. В случае сложных DTO и различных по виду запросов стоит такие фикстуры создать для каждого более-менее отличного запроса, желательно реального, взятого из браузера или из логов.
В Spring Boot имеется аннотация @WebMvcTest, которая позволяет писать как раз такие unit-тесты:
Вот такими манипуляциями можно проверить и View-слой SpringBoot приложения. А как проверить DAO/Repository-слой, мы узнаем в следующей заметке.
Модульное и интеграционное тестирование - неотъемлемая часть вашей повседневной жизни как разработчика. Однако для новичков Spring Boot написание содержательных тестов для своих приложений оказывается проблемой:
С чего начать мои усилия по тестированию?
Как Spring Boot может помочь мне в написании эффективных тестов?
Какие библиотеки мне использовать?
В этом блоге вы получите обзор того, как модульное и интеграционное тестирование работает со Spring Boot. Кроме того, вы узнаете, на каких функциях и библиотеках Spring следует сосредоточиться в первую очередь. Эта статья действует как агрегатор, и в нескольких местах вы найдете ссылки на другие статьи и руководства, которые более подробно объясняют концепции.
Модульное тестирование с помощью Spring Boot
Модульные тесты составляют основу вашей стратегии тестирования. Каждый проект Spring Boot, который вы запускаете с помощью Spring Initializr, имеет прочную основу для написания модульных тестов. Настраивать практически нечего, так как Spring Boot Starter Test включает в себя все необходимые строительные блоки.
Помимо включения и управления версией Spring Test, этот Spring Boot Starter включает и управляет версиями следующих библиотек:
Библиотеки проверки утверждений, такие как AssertJ, Hamcrest, JsonPath и т. Д.
В большинстве случаев ваши модульные тесты не нуждаются в какой-либо конкретной функции Spring Boot или Spring Test, поскольку они будут полагаться исключительно на JUnit и Mockito.
С помощью модульных тестов вы изолированно тестируете, например, свои *Service классы и имитируете каждого сотрудника тестируемого класса:
Как видно из раздела import тестового класса выше, Spring вообще не включается. Следовательно, вы можете применять методы и знания, полученные из модульного тестирования любого другого приложения Java.
Вот почему важно изучить основы JUnit 4/5 и Mockito, чтобы максимально использовать возможности модульного тестирования.
Лучшим подходом здесь является работа с нарезанным контекстом Spring, который можно легко автоматически настроить с помощью аннотаций теста Spring Boot.
Тесты фрагментов Spring Context
В дополнение к традиционным модульным тестам вы можете писать тесты с помощью Spring Boot, которые нацелены на определенные части (фрагменты) вашего приложения. TestContext Spring фреймворка вместе с Spring Boot адаптирует Spring контекст с достаточным количеством компонентов для конкретного теста.
Цель этих тестов - изолированно протестировать определенную часть вашего приложения без запуска всего приложения. Это сокращает как время выполнения теста, так и потребность в обширной настройке теста.
Как назвать такие тесты? На мой взгляд, они не попадают на 100% в категорию модульных или интеграционных тестов. Некоторые разработчики называют их модульными тестами, потому что они тестируют, например, один контроллер изолированно. Другие разработчики относят их к интеграционным тестам, поскольку в них задействована поддержка Spring. Как бы вы их ни называли, убедитесь, что у вас есть общее понимание, по крайней мере, в вашей команде.
Spring Boot предлагает много аннотаций, позволяющих проверить различные части вашего приложения в отдельности: @JsonTest , @WebMvcTest , @DataMongoTest , @JdbcTest и т.д.
Все они автоматически настраивают фрагменты Spring TestContext и включают только компоненты Spring, относящиеся к тестированию определенной части вашего приложения. Я посвятил целую статью представлению наиболее распространенных из этих аннотаций и объяснению их использования.
Две наиболее важные аннотации (сначала изучите их):
Также доступны аннотации для других нишевых частей вашего приложения:
При их использовании важно понимать, какие компоненты входят в состав, TestContext а какие нет. Документация Javadoc каждой аннотации объясняет выполненную автоконфигурацию и цель.
Вы всегда можете расширить контекст автонастройки для своего теста, явно импортировав компоненты с помощью @Import или определив дополнительные компоненты Spring Beans, используя @TestConfiguration :
Ловушка JUnit 4 и JUnit 5
Одна большая ловушка, с которой я довольно часто сталкиваюсь, отвечая на вопросы на Stack Overflow, - это сочетание JUnit 4 и JUnit 5 (JUnit Jupiter, если быть более конкретным) в одном тесте. Использование API разных версий JUnit в одном тестовом классе может привести к неожиданным результатам и сбоям.
Важно следить за импортом, особенно за @Test аннотацией:
Другими индикаторами для JUnit 4 являются: @RunWith , @Rule , @ClassRule , @Before , @BeforeClass , @After , @AfterClass .
С помощью JUnit 5 vintage-engine ваш набор тестов может содержать как тесты JUnit 3/4, так и JUnit Jupiter, но каждый тестовый класс может использовать только одну конкретную версию JUnit. Рассмотрите возможность миграции существующих тестов, чтобы использовать различные новые функции JUnit Jupiter (параметризованные тесты, распараллеливание, модель расширения и т. д.). Вы можете постепенно мигрировать свой набор тестов, так как вы можете запускать тесты JUnit 3/4 рядом с тестами JUnit 5.
Документация JUnit включает советы по миграции JUnit 4, а также имеются инструменты (JUnit Pioneer или эта функция IntelliJ) для автоматической миграции тестов (например, импорт или проверки утверждений).
После того, как вы мигрировали свой набор тестов на JUnit 5, важно исключить любое появление устаревшей версии JUnit. Не все в вашей команде могут постоянно обращать пристальное внимание на импорт библиотек тестирования. Чтобы избежать случайного смешивания разных версий JUnit, исключение их из вашего проекта помогает всегда выбирать правильный импорт:
Кроме Spring Boot Starter Test другие зависимости тестования также могут включать более старые версии JUnit:
Чтобы избежать (случайного) включения зависимостей JUnit 4 в будущем, вы можете использовать Maven Enforcer Plugin и определить его как запрещенную зависимость. Это приведет к сбою сборки, как только кто-то включит новую тестовую зависимость, которая транзитивно потянет JUnit 4.
Обратите внимание, что, начиная с Spring Boot 2.4.0, зависимость Spring Boot Starter Test больше не включает vintage-engine файл по умолчанию.
Интеграционные тесты с Spring Boot: @SpringBootTest
С помощью интеграционных тестов вы обычно тестируете несколько компонентов вашего приложения в комбинации. Большая часть времени вы будете использовать @SpringBootTest аннотацию для этой цели и доступ к приложению с внешней стороны с помощью либо WebTestClient или TestRestTemplate .
@SpringBootTest будет заполнять весь контекст приложения для теста. При использовании этой аннотации важно понимать атрибут webEnvironment . Без указания этого атрибута такие тесты не будут запускать встроенный контейнер сервлетов (например, Tomcat) и вместо этого будут использовать имитацию среды сервлетов. Следовательно, ваше приложение не будет доступно через локальный порт.
Вы можете переопределить это поведение, указав либо, DEFINE_PORT либо RANDOM_PORT :
Для интеграционных тестов, которые запускают встроенный контейнер сервлетов, вы можете затем внедрить порт своего приложения и получить к нему доступ извне, используя TestRestTemplate или WebTestClient :
Здесь в игру вступают Testcontainers. Testcontainers будет управлять жизненным циклом любого Docker контейнера для вашего теста:
Для ознакомления с Testcontainers рассмотрите следующие ресурсы:
Кроме того, TestContext Spring фреймворк имеет удобную функцию кеширования и повторного использования, а также уже запущенный контекст. Это может помочь сократить время сборки и значительно улучшить циклы обратной связи.
Сквозные тесты с Spring Boot
Целью сквозных (E2E) тестов является проверка системы с точки зрения пользователя. Сюда входят тесты для основных сценариев работы пользователя (например, размещение заказа или создание нового клиента). По сравнению с интеграционными тестами такие тесты обычно включают пользовательский интерфейс (если он есть).
Вы также можете выполнить тесты E2E для развернутой версии приложения, например, в среде dev или staging прежде чем приступить к развертыванию в рабочей среде.
Для приложений, которые используют рендеринг на стороне сервера (например, Thymeleaf) или автономной системы, когда серверная часть Spring Boot обслуживает интерфейс, вы можете использовать @SpringBootTest для этих тестов.
Как только вам нужно взаимодействовать с браузером, Selenium обычно является выбором по умолчанию. Если вы какое-то время работали с Selenium, вы сможете обнаружить, что снова и снова реализуете одни и те же вспомогательные функции. Для лучшего взаимодействия с разработчиками и уменьшения головной боли при написании тестов, предполагающих взаимодействие с браузером, рассмотрите вариант Selenide. Selenide - это абстракция поверх низкоуровневого API Selenium для написания стабильных и кратких тестов браузера.
Следующий тест демонстрирует, как получить доступ и протестировать общедоступную страницу приложения Spring Boot с помощью Selenide:
Для компонентов инфраструктуры, которые необходимо запустить для тестов E2E, Testcontainers играет большую роль. Если вам нужно запустить несколько Docker контейнеров, вам пригодится модуль Docker Compose из Testcontainers :
Резюме
Spring Boot предлагает отличную поддержку как для модульного, так и для интеграционного тестирования. Это делает тестирование первоклассным гражданином, поскольку каждый проект Spring Boot включает в себя Spring Boot Starter Test. Этот стартер подготовит ваш базовый набор инструментов для тестирования с необходимыми библиотеками тестирования.
Кроме того, аннотации Spring Boot test упрощают написание тестов для различных частей вашего приложения. Вы получите специально созданный Spring TestContext только с соответствующими Spring beans.
Чтобы познакомиться с модульными и интеграционными тестами для ваших проектов Spring Boot, рекомендуются следующие шаги:
Избегайте ловушки JUnit 4 и JUnit 5.
Ознакомьтесь с различными аннотациями тестирования Spring Boot, которые автоматически настраивают фрагменты контекста.
Узнайте, как Spring TestContext Caching может помочь сократить общее время выполнения вашего набора тестов.
Если ваш тест по-прежнему не выполняет то, что вы ожидаете, не сокращайте свои усилия по тестированию, оправдывая это тем, что Spring Boot - это слишком много магии. Как в документации Spring, так и в различных блогах доступен отличный материал.
Кроме того, активность сообщества на Stack Overflow для таких тегов, как spring-test , spring-boot-test или spring-test-mvc , довольно хороша, и есть большая вероятность, что вы получите помощь. Я также часто отвечаю на вопросы, связанные с тестированием, на Stack Overflow.
Удачного модульного и интеграционного тестирования с помощью Spring Boot,
Нередко пользователи пытаются передать в приложение некорректные данные. Это происходит либо из злого умысла, либо по ошибке. Поэтому стоит проверять данные на соответствие бизнес-требованиям.
Нередко пользователи пытаются передать в приложение некорректные данные. Это происходит либо из злого умысла, либо по ошибке. Поэтому стоит проверять данные на соответствие бизнес-требованиям.
Эту задачу решает Bean Validation. Он интегрирован со Spring и Spring Boot. Hibernate Validator считается эталонной реализацией Bean Validation.
Для проверки данных используются аннотации над полями класса. Это декларативный подход, который не загрязняет код.
При передаче размеченного таким образом объекта класса в валидатор, происходит проверка на ограничения.
Добавьте стартер в проект, чтобы включить валидацию:
Валидация в Controller
- тело запроса
- переменные пути (например, id в /foos/)
- параметры запроса
Рассмотрим каждый из них подробнее.
Валидация тела запроса
Тело запроса POST и PUT обычно содержит данные в формате JSON. Spring автоматически сопоставляет входящий JSON с объектом Java.
Проверяем соответствует ли входящий Java объект нашим требованиям.
- Поле name не должно быть пустым или null.
- Поле numberBetweenOneAndTen должно быть от 1 до 10, включительно.
- Поле ipAddress должно содержать строку в формате IP-адреса.
Достаточно добавить для входящего параметра personDto аннотацию @Valid , чтобы передать объект на валидацию, прежде чем делать с ним что-то еще.
В демонстрационном проекте для удобства вы можете использовать Swagger, о нем я писал в статье: Документирование API с помощью OpenAPI 3 и Swagger. Я же буду использовать Postman.
Вызываем наш POST метод и передаем в него не валидные данные.
Postman возвращает нам ошибку, а в консоли получаем исключение, которое сообщает нам что у нас 2 ошибки валидации.
Проверка переменных пути и параметров запроса
При проверке переменных пути и параметров запроса не проверяются сложные Java-объекты, так как path-переменные и параметры запроса являются примитивными типами, такими как int , или их аналогами: Integer или String .
Вместо аннотации поля класса, как описано выше, добавляют аннотацию ограничения (в данном случае @Min ) непосредственно к параметру метода в контроллере:
Обратите внимание, что необходимо добавить @Validated в контроллер на уровне класса, чтобы проверять параметры метода. В этом случае аннотация @Validated устанавливается на уровне класса, даже если она присутствует на методах.
Валидация в сервисном слое
Можно проверять данные на любых компонентах Spring. Для этого используется комбинация аннотаций @Validated и @Valid .
Аннотация @Validated устанавливается только на уровне класса, так что не ставьте ее на метод в данном случае.
Казалось бы, пример такой же как и в контроллере и логично ожидать MethodArgumentNotValidException , но будет выброшен ConstraintViolationException и 500 ошибка.
Валидация сущностей JPA
Persistence Layer – это последняя линия проверки данных. По умолчанию Spring Data использует Hibernate, который поддерживает Bean Validation из коробки.
Обычно мы не хотим делать проверку так поздно, поскольку это означает, что бизнес-код работал с потенциально невалидными объектами, что может привести к непредвиденным ошибкам.
Допустим, необходимо хранить объекты нашего класса PersonDto в базе данных.
Когда репозиторий пытается сохранить не валидный PersonDto , чьи аннотации ограничений нарушаются, выбрасывается ConstraintViolationException .
Bean Validation запускается Hibernate только после того как EntityManager вызовет flush.
Чтобы отключить Bean Validation в репозиториях, достаточно установить свойство Spring Boot spring.jpa.properties.javax.persistence.validation.mode равным null .
Конкретизация ошибок
Сначала нужно определить эту структуру данных. Назовем ее ValidationErrorResponse и она содержит список объектов Violation :
Затем создадим глобальный ControllerAdvice , который обрабатывает все ConstraintViolationExventions , которые пробрасываются до уровня контроллера. Чтобы отлавливать ошибки валидации и для тел запросов, мы также будем перехватывать и MethodArgumentNotValidExceptions :
Здесь информацию о нарушениях из исключений переводится в нашу структуру данных ValidationErrorResponse .
Валидация конфигурации приложения
Spring Boot аннотация @ConfigurationProperties используется для связывания свойств из application.properties с Java объектом.
Данные из application необходимы для стабильной работы приложения. Bean Validation поможет обнаружить ошибку в этих данных при старте приложения.
Допустим имеется следующий конфигурационный класс:
При попытке запуска с недействительным адресом электронной почты получаем ошибку:
Стандартные ограничения
Каждая аннотация имеет следующие поля:
Рассмотрим популярные ограничения.
@NotNull и @Null
@NotNull - аннотированный элемент не должен быть null. Принимает любой тип.
@Null - аннотированный элемент должен быть null. Принимает любой тип.
@NotBlank и @NotEmpty
@NotBlank - аннотированный элемент не должен быть null и должен содержать хотя бы один непробельный символ. Принимает CharSequence .
@NotEmpty - аннотированный элемент не должен быть null или пустым . Поддерживаемые типы:
- CharSequence
- Collection . Оценивается размер коллекции
- Map . Оценивается размер мапы
- Array . Оценивается длина массива
@NotBlank применяется только к строкам и проверяет, что строка не пуста и не состоит только из пробелов.
@NotNull применяется к CharSequence , Collection , Map или Array и проверяет, что объект не равен null . Но при этом он может быть пуст.
@NotEmpty применяется к CharSequence , Collection , Map или Array и проверяет, что он не null имеет размер больше 0.
Аннотация @Size(min=6) пропустит строку состоящую из 6 пробелов и/или символов переноса строки, а @NotBlank не пропустит.
Размер аннотированного элемента должен быть между указанными границами, включая сами границы. null элементы считаются валидными.
- CharSequence . Оценивается длина последовательности символов
- Collection . Оценивается размер коллекции
- Map . Оценивается размер мапы
- Array . Оценивается длина массива
Группы валидаций
Некоторые объекты участвуют в разных вариантах использования.
Возьмем типичные операции CRUD: при обновлении и создании, скорее всего, будет использоваться один и тот же класс. Тем не менее, некоторые валидации должны срабатывать при различных обстоятельствах:
- только перед созданием
- только перед обновлением
- или в обоих случаях
Функция Bean Validation, которая позволяет нам внедрять такие правила проверки, называется “Validation Groups”.
Все аннотации ограничений имеют поле groups . Это поле используется для передачи любых классов, каждый из которых определяет группу проверки.
Для нашего примера CRUD определим два маркерных интерфейса OnCreate и OnUpdate :
Затем используем эти интерфейсы с любой аннотацией ограничения:
Это позволит убедиться, что id пуст при создании и заполнен при обновлении.
Spring поддерживает группы проверки только с аннотацией @Validated
Обратите внимание, что аннотация @Validated применяется ко всему классу. Чтобы определить, какая группа проверки активна, она также применяется на уровне метода.
Использование групп проверки может легко стать анти-паттерном. При использовании групп валидации сущность должна знать правила валидации для всех случаев использования (групп), в которых она используется.
Создание своего ограничения
Если имеющихся аннотаций ограничений недостаточно, то создайте новые.
Напишем валидатор, который будет проверять, что строка начинается с большой буквы.
Сначала создаем пользовательскую аннотацию @CapitalLetter :
Реализация валидатора выглядит следующим образом:
Теперь можно использовать аннотацию @CapitalLetter , как и любую другую аннотацию ограничения.
Принудительный вызов валидации
Для принудительного вызова проверки, без использования Spring Boot, создайте валидатор вручную.
Тем не менее, Spring Boot предоставляет предварительно сконфигурированный экземпляр валидатора. Внедрив этот экземпляр в сервис не придется создавать его вручную.
Читайте также: