Автор оригинала: Rayven Yor Esplanada.
Вступление
Тестирование системы является важным этапом в Жизненном цикле разработки программного обеспечения (SDLC) . Тестирование повышает надежность кода, надежность и гарантирует высокое качество программного обеспечения, поставляемого клиентам, если оно реализовано правильно.
Тестированию придается все большее значение с тех пор, как Разработка на основе тестов (TDD) стала заметным процессом в разработке программного обеспечения. Разработка на основе тестирования предполагает преобразование требований в тестовые наборы и использование этих тестовых наборов для обеспечения качества кода привратника. Код будет считаться неприемлемым, если он не пройдет ни один из тестовых случаев, объявленных в системе, и чем больше тестовых случаев будет соответствовать требованиям продукта, тем лучше. Кодовая база значительно расширена, но подтверждает тот факт, что система отвечает заданным требованиям.
API-интерфейсы REST обычно тщательно тестируются во время интеграционного тестирования . Однако хороший разработчик должен протестировать конечные точки REST еще до интеграции в свои Модульные тесты , поскольку они являются жизненно важной частью кода , поскольку это единственная точка доступа каждого объекта, желающего использовать службы на сервере.
В этом руководстве будет показано, как реализовать модульные тесты для API REST в среде загрузки Spring. Эта статья посвящена тестированию бизнес-уровня, который состоит из API, конечных точек и контроллеров в базе кода.
Требования
Для этого руководства вам понадобятся следующие спецификации:
- Пружинный ботинок v2.0+
- JDK v1.8+
- JUnit 5 – Самый популярный и широко используемый фреймворк для тестирования Java.
- Mockito – Фреймворк общего назначения для насмешек и заглушения сервисов и объектов.
- MockMvc – Модуль Spring для выполнения интеграционного тестирования во время модульного тестирования .
- Ломбок – Удобная библиотека для сокращения шаблонного кода.
- Любая среда IDE, поддерживающая Java и Spring Boot (IntelliJ, VSC, NetBeans и т.д.)
- Почтальон,
curl
или любой HTTP-клиент
Если вам все еще не совсем удобно создавать API REST с помощью Spring Boot – прочитайте наше руководство по созданию API REST для Spring Boot .
Мы будем использовать Ломбок в качестве удобной библиотеки, которая автоматически генерирует геттеры, сеттеры и конструкторы, и это полностью необязательно.
Настройка проекта
Самый простой способ начать работу с проектом загрузки со скелетной пружиной-это Spring Initializr :
Помимо этого, нам понадобится несколько дополнительных зависимостей, добавленных в pom.xml
файл.
Добавление Зависимостей Модульного Тестирования
Давайте продолжим и добавим зависимости, необходимые для модульного тестирования.
Для JUnit 5 , последней версии, нам нужно будет исключить JUnit 4 из зависимости spring-boot-starter-test
, поскольку по умолчанию он добавляет JUnit 4. Чтобы добавить JUnit 5 в свой проект, добавьте junit-jupiter-engine
в свои зависимости под вашим основным pom.xml
файл после исключения JUnit 4 из springboot-starter-теста |/зависимости.
MockMvc уже включен в spring-boot-starter-test
по умолчанию, звук>spring-boot-starter-тест, если вы исключите его и используете другое его исполнение, тогда все в порядке:
org.springframework.boot spring-boot-starter-test test junit junit org.junit.jupiter junit-jupiter-engine test
Помимо JUnit 5, нам также необходимо добавить зависимости, чтобы включить Mockito в вашей системе. Для этого просто добавьте mockito-core
в свои зависимости и укажите значение test
в качестве области действия для этой зависимости:
org.mockito mockito-core test
Примечание: Если вы не укажете версию
для своих зависимостей, он просто получит последнюю доступную стабильную версию этой зависимости из репозитория, из которого вы загружаете.
Теперь мы можем приступить к кодированию уровней домена и сохраняемости.
Уровни домена и сохраняемости
Доменный уровень – Создание модели записи пациента
Образец сущности, который мы будем использовать на протяжении всего урока, будет состоять из записей пациентов, содержащих несколько типичных полей для записи пациента.
Не забудьте аннотировать свой класс модели с помощью @Entity
, чтобы указать, что класс сопоставлен с таблицей в базе данных. Также можно указать аннотацию @Table
, чтобы убедиться, что класс указывает на правильную таблицу.
Помимо этих двух аннотаций, включите аннотации утилиты Lombok ( @Data, @No/AllArgsConstructor, @Builder
), чтобы вам не нужно было объявлять ваши геттеры, сеттеры и конструкторы, поскольку Lombok уже делает это за вас.
Поля String
и Integer
помечены @NonNull
, чтобы они не имели null
или пустое значение для целей проверки:
@Entity @Table(name = "patient_record") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class PatientRecord { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long patientId; @NonNull private String name; @NonNull private Integer age; @NonNull private String address; }
Уровень сохраняемости – Создание хранилища записей пациентов
Следующим шагом является создание репозитория JPA для предоставления методов, позволяющих легко извлекать записи пациентов из базы данных и манипулировать ими без необходимости ручного внедрения.
Давайте аннотируем интерфейс с помощью @Репозитория
и расширим JpaRepository
, чтобы создать правильно работающий интерфейс JpaRepository. В этом руководстве у JpaRepository не будет никаких пользовательских методов, поэтому тело должно быть пустым:
@Repository public interface PatientRecordRepository extends JpaRepository{}
Теперь, когда мы создали наш простой домен и уровень сохраняемости, давайте перейдем к кодированию компонентов для вашего бизнес-уровня.
Бизнес-уровень
Бизнес – уровень состоит из контроллеров, которые обеспечивают связь с сервером и обеспечивают доступ к предоставляемым им службам.
Для этого урока давайте создадим контроллер, который предоставляет 4 простых конечных точки REST, по одной для каждой операции CRUD: Создание, чтение, обновление и Удаление .
Создание экземпляра класса контроллера – Контроллер записи пациентов
Во-первых, аннотируйте свой класс контроллера аннотацией @RestController
, чтобы сообщить DispatcherServlet
, что этот класс содержит методы сопоставления запросов.
Если вы раньше не работали с контроллерами Rest , прочитайте наше руководство по Аннотации @Controller и @RestController .
Чтобы предоставить услуги CRUD для методов, объявите Репозиторий записей пациентов
интерфейс в классе контроллера и аннотируйте его с помощью @Autowired
, чтобы неявно внедрить объект, чтобы вам не нужно было создавать его вручную.
Вы также можете аннотировать класс @RequestMapping
свойством value
, чтобы инициализировать базовый путь для всех методов сопоставления запросов в классе. Давайте установим для свойства значение
значение запись пациента/|, чтобы базовый путь был интуитивно понятным:
@RestController @RequestMapping(value = "/patient") public class PatientRecordController { @Autowired PatientRecordRepository patientRecordRepository; // CRUD methods to be added }
Теперь давайте создадим несколько методов, которые составляют функциональность CRUD, которую мы будем модульно тестировать.
Получение пациентов – Обработчик запроса GET
Давайте создадим два разных метода GET
: один для получения всех записей пациентов в базе данных, а другой для получения одной записи с идентификатором пациента.
Чтобы указать , что метод сопоставляется с помощью GET
, аннотируйте его аннотацией @GetMapping
. Если вы не знакомы с производными вариантами @RequestMapping
– вы можете прочитать наше руководство по Весенним аннотациям: @RequestMapping и его варианты :
@GetMapping public ListgetAllRecords() { return patientRecordRepository.findAll(); } @GetMapping(value = "{patientId}") public PatientRecord getPatientById(return patientRecordRepository.findById(patientId).get(); }
Поскольку методу get Patient По идентификатору()
требуется параметр ( Идентификатор пациента
), мы предоставим его через путь, аннотировав его с помощью @PathVariable
и указав значение
свойство переменной. Кроме того, установите свойство value
аннотации @GetMapping
, чтобы сопоставить переменную пути с ее фактическим местом в базовом пути.
Создание Обработчика запросов Пациентов после отправки
Для добавления новых записей пациентов потребуется метод POST
-сопоставления. Метод примет Запись пациента
параметр, аннотированный @RequestBody
и @Действительный
. Аннотация @Valid
гарантирует, что все ограничения в базе данных и в классе сущностей будут перепроверены перед обработкой данных.
Если вы не знакомы с процессом десериализации HTTP – запросов к объектам Java-прочитайте наше руководство о том, как получить тело HTTP-сообщения в Spring Boot с помощью @RequestBody:
@PostMapping public PatientRecord createRecord(@RequestBody @Valid PatientRecord patientRecord) { return patientRecordRepository.save(patientRecord); }
Прежде чем перейти к другим методам запроса, давайте создадим одно общее исключение для всех исключений, встречающихся в базе кода, и назовем его Исключение InvalidRequestException
. Для кода состояния давайте использовать BAD_REQUEST
код состояния 400
.
Чтобы обработать исключения и преобразовать их в код состояния для возврата вызывающему, давайте объявим простой класс исключений, который расширяет класс RuntimeException
:
@ResponseStatus(HttpStatus.BAD_REQUEST) class InvalidRequestException extends RuntimeException { public InvalidRequestException(String s) { super(s); } }
Обновление Обработчика запросов пациентов – PUT
Для обработки обновлений – для метода PUT
давайте аннотируем его @PutMapping
и потребуем параметр, аннотированный @RequestBody
, содержащий обновленную Запись пациента
, аналогичную POST
сопоставлению.
Мы хотим убедиться, что запись существует для целей проверки, используя идентификатор пациента
. Поскольку это запрос PUT
, запись, подлежащая обновлению, должна существовать в базе данных, в противном случае это недопустимый запрос. Кроме того, создайте исключение InvalidRequestException
, если тело запроса или идентификатор пациента
поле равно нулю
:
@PutMapping public PatientRecord updatePatientRecord(@RequestBody PatientRecord patientRecord) throws NotFoundException { if (patientRecord == null || patientRecord.getPatientId() == null) { throw new InvalidRequestException("PatientRecord or ID must not be null!"); } OptionaloptionalRecord = patientRecordRepository.findById(patientRecord.getPatientId()); if (optionalRecord.isEmpty()) { throw new NotFoundException("Patient with ID " + patientRecord.getPatientId() + " does not exist."); } PatientRecord existingPatientRecord = optionalRecord.get(); existingPatientRecord.setName(patientRecord.getName()); existingPatientRecord.setAge(patientRecord.getAge()); existingPatientRecord.setAddress(patientRecord.getAddress()); return patientRecordRepository.save(existingPatientRecord); }
Удаление Пациентов – Обработчик запроса на УДАЛЕНИЕ
Теперь мы также захотим иметь возможность удалять пациентов. Этот метод будет помечен @DeleteMapping
и примет параметр идентификатор пациента
и удалит пациента с этим идентификатором, если он существует. Метод вернет исключение и 400
код статуса, если пациент не существует. Как и метод GET
, который извлекает пациента по идентификатору, добавьте свойство value
в аннотацию @DeleteMapping
, а также @PathVariable
:
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
@DeleteMapping(value = "{patientId}") public void deletePatientById(@PathVariable(value = "patientId") Long patientId) throws NotFoundException { if (patientRecordRepository.findById(patientId).isEmpty()) { throw new NotFoundException("Patient with ID " + patientId + " does not exist."); } patientRecordRepository.deleteById(patientId); }
Теперь наш бизнес-слой загрунтован и готов! Мы можем пойти дальше и написать для него модульные тесты. Если вы хотите прочитать более подробное руководство по созданию API REST в Spring Boot – прочитайте наше руководство по созданию API REST для Spring Boot .
Давайте перейдем к созданию модульных тестов для API REST в нашем классе контроллера с использованием JUnit , Mockito и MockMvc .
Модульное тестирование API-интерфейсов Spring Boot REST
MockMvc – это решение, позволяющее модульное тестирование веб-уровня . Обычно тестирование API-интерфейсов REST выполняется во время интеграционного тестирования, что означает, что приложение должно запускаться в контейнере, чтобы проверить, работают ли конечные точки или нет. MockMvc позволяет тестировать веб-уровень (т. е. бизнес-уровень или уровень контроллера) во время модульного тестирования с соответствующими конфигурациями, но без дополнительных затрат на развертывание приложения.
Наличие модульных тестов для веб-уровня также значительно увеличит охват тестового кода для вашего приложения и отразится в таких инструментах, как Sonar и JaCoCo .
Каталог модульных тестов обычно находится в том же исходном каталоге в каталоге test/java/package . По умолчанию файловая структура модульного теста будет выглядеть следующим образом:
Project: ├─src ├───main │ ├───java │ └───resources └───test └───java
Также хорошей практикой и стандартным соглашением является называть ваши тестовые классы так же, как и контроллеры, которые вы тестируете, с суффиксом – Test
. Например, если мы хотим протестировать Контроллер записей пациентов
, мы создадим класс Контроллер записей пациентов
в соответствующем пакете в src/test/java
.
Вместо аннотирования тестового класса с помощью @SpringBootTest
мы будем использовать аннотацию @WebMvcTest
, чтобы зависимости, которые будут загружены при запуске тестового класса, напрямую влияли на класс контроллера. Любые службы, репозитории и подключения к базам данных не будут настроены и загружены после запуска теста, поэтому вам придется имитировать все эти компоненты с помощью Mockito .
В этом случае нам нужно указать только один контроллер – PatientRecordController.class
, для @WebMvcTest
аннотации. Если в одном тестовом классе введено несколько контроллеров, разделите контроллеры запятой ,
и заключите их в пару фигурных скобок {}
:
@WebMvcTest(PatientRecordController.class) public class PatientRecordControllerTest { @Autowired MockMvc mockMvc; @Autowired ObjectMapper mapper; @MockBean PatientRecordRepository patientRecordRepository; PatientRecord RECORD_1 = new PatientRecord(1l, "Rayven Yor", 23, "Cebu Philippines"); PatientRecord RECORD_2 = new PatientRecord(2l, "David Landup", 27, "New York USA"); PatientRecord RECORD_3 = new PatientRecord(3l, "Jane Doe", 31, "New York USA"); // ... Test methods TBA }
Здесь мы объявили объект MockMvc
и снабдили его аннотацией @Autowired
, что разрешено в данном контексте , поскольку MockMvc
настроен автоматически и является частью зависимостей, загружаемых для этого тестового класса. Мы также автоматически подключили ObjectMapper
объект; это будет использоваться позже.
Интерфейс Хранилище записей пациентов
используется во всех конечных точках API, поэтому мы издевались над ним с помощью @Mockbeat
. Наконец, мы создали несколько Записей пациентов
экземпляров для целей тестирования.
Модульное тестирование обработчиков запросов GET
Теперь мы можем продолжить и сделать наш первый тестовый случай – также известный как модульный тест . Мы будем тестировать метод getAllRecords ()
, наш обработчик запросов GET
. Для каждого модульного теста мы создадим один метод, который будет проверять другой. Каждый модульный тест снабжен аннотацией @Test
, чтобы JUnit мог подобрать их и поместить в список всех тестов, которые необходимо выполнить:
@Test public void getAllRecords_success() throws Exception { Listrecords = new ArrayList<>(Arrays.asList(RECORD_1, RECORD_2, RECORD_3)); Mockito.when(patientRecordRepository.findAll()).thenReturn(records); mockMvc.perform(MockMvcRequestBuilders .get("/patient") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasSize(3))) .andExpect(jsonPath("$[2].name", is("Jane Doe"))); }
Метод Mockito
когда().thenReturn()
цепочка издевается над вызовом метода getAllRecords()
в репозитории JPA, поэтому каждый раз, когда метод вызывается в контроллере, он возвращает указанное значение в параметре метода thenReturn ()
. В этом случае он возвращает список из трех заранее заданных записей пациентов вместо фактического вызова базы данных.
MockMvc.perform()
принимает MockMvcRequest
и издевается над вызовом API, заданным полями объекта. Здесь мы создали запрос через MockMvcRequestBuilders
и указали только GET
путь и ContentType
свойство , поскольку конечная точка API не принимает никаких параметров.
После выполнения perform ()
, и Ожидание()
методы впоследствии привязываются к нему и проверяются на соответствие результатам, возвращаемым методом. Для этого вызова мы установили 3 утверждения в методах andExpect ()
: что ответ возвращает 200
или код состояния OK
, ответ возвращает список размеров 3
, и третий Запись пациента
объект из списка имеет имя
свойство Джейн Доу
.
Методы со статическими ссылками здесь – JSONPath()
, имеет размер()
и является()
принадлежат классам MockMvcResultMatchers
и Сопоставителей
соответственно:
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.hamcrest.Matchers.*;
Вы, конечно, можете статически ссылаться на них:
.andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.hasSize(3))) .andExpect(MockMvcResultMatchers.jsonPath("$[2].name", Matchers.is("Jane Doe")));
Хотя, если у вас много и вы ожидаете()
заявлений, связанных вместе, – это довольно быстро станет повторяющимся и раздражающим.
Примечание: Все эти утверждения не должны быть неудачными для прохождения модульного теста. Выполнение этого кода приводит к:
Теперь давайте добавим еще один тестовый случай для метода getparentbyid ()
. Прямо под предыдущим модульным тестом мы можем написать новый:
@Test public void getPatientById_success() throws Exception { Mockito.when(patientRecordRepository.findById(RECORD_1.getPatientId())).thenReturn(java.util.Optional.of(RECORD_1)); mockMvc.perform(MockMvcRequestBuilders .get("/patient/1") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", notNullValue())) .andExpect(jsonPath("$.name", is("Rayven Yor"))); }
Здесь мы проверяем, является ли результат нулевым
, утверждая, что это не , и проверяем, равно ли имя
поле возвращаемого объекта "Rayven Yor"
. Если мы сейчас запустим весь Класс контроллера записей пациентов|/, нас встретят:
Модульное тестирование обработчиков запросов POST
Теперь, когда мы протестировали способность API извлекать отдельные идентифицируемые записи, а также список всех записей, давайте проверим его способность сохранять записи . Обработчик POST
запроса принимает POST
запрос и отображает предоставленные значения в Запись пациента
POJO с помощью @RequestBody
аннотации. Наш тестовый модуль также примет JSON и сопоставит значения в Запись пациента
POJO с помощью ObjectMapper
, который мы подключали ранее. Мы также сохраним ссылку на возвращенный MockHttpServletRequestBuilder
после того, как он будет сгенерирован MockMvcRequestBuilders
, чтобы мы могли проверить возвращенные значения:
@Test public void createRecord_success() throws Exception { PatientRecord record = PatientRecord.builder() .name("John Doe") .age(47) .address("New York USA") .build(); Mockito.when(patientRecordRepository.save(record)).thenReturn(record); MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/patient") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(this.mapper.writeValueAsString(record)); mockMvc.perform(mockRequest) .andExpect(status().isOk()) .andExpect(jsonPath("$", notNullValue())) .andExpect(jsonPath("$.name", is("John Doe"))); }
Повторный запуск класса приводит к:
Модульное тестирование обработчиков запросов PUT
Обработчик PUT
запроса имеет немного больше логики, чем два предыдущих. Он проверяет, предоставили ли мы идентификатор, что приводит к исключению, если он отсутствует. Затем он проверяет, действительно ли идентификатор принадлежит записи в базе данных, создавая исключение, если это не так. Только тогда он фактически обновляет запись в базе данных, если идентификатор не null
и он действительно принадлежит записи.
Мы создадим три метода тестирования, чтобы проверить, работают ли все три аспекта этого метода: по одному для успешного выполнения и по одному для каждого из возможных ошибочных состояний:
@Test public void updatePatientRecord_success() throws Exception { PatientRecord updatedRecord = PatientRecord.builder() .patientId(1l) .name("Rayven Zambo") .age(23) .address("Cebu Philippines") .build(); Mockito.when(patientRecordRepository.findById(RECORD_1.getPatientId())).thenReturn(Optional.of(RECORD_1)); Mockito.when(patientRecordRepository.save(updatedRecord)).thenReturn(updatedRecord); MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/patient") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(this.mapper.writeValueAsString(updatedRecord)); mockMvc.perform(mockRequest) .andExpect(status().isOk()) .andExpect(jsonPath("$", notNullValue())) .andExpect(jsonPath("$.name", is("Rayven Zambo"))); }
Однако в тех случаях, когда либо входные данные неверны, либо база данных просто не содержит объект, который мы пытаемся обновить, приложение должно реагировать исключением. Давайте проверим это:
@Test public void updatePatientRecord_nullId() throws Exception { PatientRecord updatedRecord = PatientRecord.builder() .name("Sherlock Holmes") .age(40) .address("221B Baker Street") .build(); MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/patient") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(this.mapper.writeValueAsString(updatedRecord)); mockMvc.perform(mockRequest) .andExpect(status().isBadRequest()) .andExpect(result -> assertTrue(result.getResolvedException() instanceof PatientRecordController.InvalidRequestException)) .andExpect(result -> assertEquals("PatientRecord or ID must not be null!", result.getResolvedException().getMessage())); } @Test public void updatePatientRecord_recordNotFound() throws Exception { PatientRecord updatedRecord = PatientRecord.builder() .patientId(5l) .name("Sherlock Holmes") .age(40) .address("221B Baker Street") .build(); Mockito.when(patientRecordRepository.findById(updatedRecord.getPatientId())).thenReturn(null); MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/patient") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(this.mapper.writeValueAsString(updatedRecord)); mockMvc.perform(mockRequest) .andExpect(status().isBadRequest()) .andExpect(result -> assertTrue(result.getResolvedException() instanceof NotFoundException)) .andExpect(result -> assertEquals("Patient with ID 5 does not exist.", result.getResolvedException().getMessage())); }
Поскольку мы сопоставили исключение InvalidRequestException
с @ResponseStatus(HttpStatus.BAD_REQUEST)
, исключение приведет к тому, что метод вернет HttpStatus.BAD_REQUEST
. Здесь мы протестировали способность нашего API REST возвращать соответствующие коды состояния при обнаружении либо ошибочных данных, либо когда кто-то пытается обновить несуществующую сущность.
Модульное тестирование обработчиков запросов на УДАЛЕНИЕ
Наконец, давайте протестируем функциональность нашего обработчика запросов DELETE
– создадим тест на успешный результат и тест на неудачный результат:
@Test public void deletePatientById_success() throws Exception { Mockito.when(patientRecordRepository.findById(RECORD_2.getPatientId())).thenReturn(Optional.of(RECORD_2)); mockMvc.perform(MockMvcRequestBuilders .delete("/patient/2") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); } @Test public void deletePatientById_notFound() throws Exception { Mockito.when(patientRecordRepository.findById(5l)).thenReturn(null); mockMvc.perform(MockMvcRequestBuilders .delete("/patient/2") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()) .andExpect(result -> assertTrue(result.getResolvedException() instanceof NotFoundException)) .andExpect(result -> assertEquals("Patient with ID 5 does not exist.", result.getResolvedException().getMessage())); }
Теперь давайте используем Maven для очистки проекта, его компиляции и запуска тестов.
Запуск программы с модульным тестированием
Во-первых, нам нужно добавить плагин Maven Surefire в pom.xml
файл, чтобы мы могли запустить команду mvn clean test
. Мы также добавим дополнительный тег конфигурации, чтобы включить PatientRecordControllerTest.java
тестовый класс, чтобы включить его в тесты Maven:
maven-surefire-plugin 2.21.0 PatientRecordControllerTest.java
Затем в каталоге нашего проекта, используя терминал, давайте запустим:
$ mvn clean test
Что приводит к:
[INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.example.demo.PatientRecordControllerTest [INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.504 s - in com.example.demo.PatientRecordControllerTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 5.633 s [INFO] Finished at: 2021-05-25T19:51:24+02:00 [INFO] ------------------------------------------------------------------------
Вывод
В этом руководстве мы рассмотрели, как создать и протестировать API Spring Boot REST с функциями CRUD с использованием JUnit, Mockito и MockMvc.