1. Обзор
Тестирование программного обеспечения является гарантией качества прикладного программного обеспечения. Разработчики Java, разрабатывающие интерфейсы, часто игнорируют модульное тестирование интерфейса. В качестве Java-разработки, если вы можете смоделировать модульное тестирование, количество ошибок будет значительно уменьшено. Spring предоставляет тестовый модуль, так что сейчас толстый братик возьмет вас поиграть в Mock unit test под springboot.Мы проведем практические операции по unit test контроллера и сервиса.
2. Введение зависимости
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Введите зависимости, как указано выше, и область действияtest. Эта зависимость предоставляет следующую библиотеку классов
- JUnit 4: самая мощная среда модульного тестирования Java-приложений.
- Spring Test & Spring Boot Test: Поддержка тестирования интеграции с Spring Boot.
- AssertJ: библиотека утверждений Java, обеспечивающая поддержку тестовых утверждений.
- Hamcrest: Объект совпадает с компонентами утверждения и ограничения.
- Mockito: Хорошо известный фреймворк для насмешек Java.
- JSONassert: библиотека утверждений JSON.
- JsonPath: библиотека манипулирования JSON XPath.
Выше приведены библиотеки классов, которые часто используются в модульном тестировании. Вам лучше провести небольшое исследование, когда у вас будет время.
3. Настройте тестовую среду
Приложение Spring Boot представляет собойSpring ApplicationContext
, общий тест не превысит этот диапазон.
Тестовая среда обеспечивает@SpringBootTest
Аннотация для обеспечения поддержки среды модульного тестирования SpringBoot. Версия JUnit, которую вы используете, еслиJUnit 4
не забудьте добавить тестовый класс@RunWith(SpringRunner.class)
,JUnit 5
Нет нужды. По умолчанию @SpringBootTest не запускает сервер. вы можете использовать егоwebEnvironment
Свойства дополнительно оптимизируют, как проходят тесты,webEnvironment
Связанные пояснения:
-
MOCK
(по умолчанию): загружает контекст веб-приложения и предоставляет фиктивную веб-среду. Встроенный сервер не будет запущен при этом выборе. Если в пути к классам нет веб-среды, будет создана обычная не-веб-среда.ApplicationContext
. вы можете сотрудничать@AutoConfigureMockMvc
или@AutoConfigureWebTestClient
Имитация веб-приложения. -
RANDOM_PORT
:нагрузкаWebServerApplicationContext
И предоставить истинную веб-среду, включенную в порту случайного веб-контейнера. -
DEFINED_PORT
:нагрузкаWebServerApplicationContext
и обеспечить реальную веб-среду иRANDOM_PORT
Разница заключается в том, чтобы включить активированный вами порт приложения SpringBoot, который обычно объявляется вapplication.yml
в файле конфигурации. -
NONE
:пройти черезSpringApplication
загрузить одинApplicationContext
. Но не предоставляет никакой веб-среды (будь то Mock или что-то другое).
Примечание. Если ваш тест с@Transactional
При аннотации транзакция откатывается после выполнения каждого тестового метода по умолчанию. но когда твойwebEnvironment
Установить какRANDOM_PORT
илиDEFINED_PORT
, то есть, когда реальная веб-среда сервлета предоставляется неявно, она не будет откатываться. Это особенно важно, чтобы гарантировать, что грязные данные не будут записаны в тестах выпуска продукции.
4. Напишите тестовые классы для проверки вашего API
Ближе к дому, сначала мы написалиBookService
Как сервисный уровень
package cn.felord.mockspringboot.service;
import cn.felord.mockspringboot.entity.Book;
/**
* The interface Book service.
*
* @author Dax
* @since 14 :54 2019-07-23
*/
public interface BookService {
/**
* Query by title book.
*
* @param title the title
* @return the book
*/
Book queryByTitle(String title);
}
Класс реализации выглядит следующим образом.Для простоты и ясности слой сохранения не тестируется.Если уровень сохранения необходимо протестировать, обратите внимание на добавление, удаление и изменение аннотаций транзакций Spring.@Transactional
Поддерживается с целью отката после тестирования.
package cn.felord.mockspringboot.service.impl;
import cn.felord.mockspringboot.entity.Book;
import cn.felord.mockspringboot.service.BookService;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
/**
* @author Dax
* @since 14:55 2019-07-23
*/
@Service
public class BookServiceImpl implements BookService {
@Override
public Book queryByTitle(String title) {
Book book = new Book();
book.setAuthor("dax");
book.setPrice(78.56);
book.setReleaseTime(LocalDate.of(2018, 3, 22));
book.setTitle(title);
return book;
}
}
Уровень контроллера выглядит следующим образом:
package cn.felord.mockspringboot.api;
import cn.felord.mockspringboot.entity.Book;
import cn.felord.mockspringboot.service.BookService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author Dax
* @since 10:24 2019-07-23
*/
@RestController
@RequestMapping("/book")
public class BookApi {
@Resource
private BookService bookService;
@GetMapping("/get")
public Book getBook(String title) {
return bookService.queryByTitle(title);
}
}
Мы в проекте Spring Boot mavenмодульный тестовый пакет test
Напишите свой собственный тестовый класс под соответствующим путем к классам
package cn.felord.mockspringboot;
import cn.felord.mockspringboot.entity.Book;
import cn.felord.mockspringboot.service.BookService;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import javax.annotation.Resource;
import java.time.LocalDate;
/**
* The type Mock springboot application tests.
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MockSpringbootApplicationTests {
@Resource
private MockMvc mockMvc;
@MockBean
private BookService bookService;
@Test
public void bookApiTest() throws Exception {
String title = "java learning";
// mockbean 开始模拟
bookServiceMockBean(title);
// mockbean 模拟完成
String expect = "{\"title\":\"java learning\",\"author\":\"dax\",\"price\":78.56,\"releaseTime\":\"2018-03-22\"}";
mockMvc.perform(MockMvcRequestBuilders.get("/book/get")
.param("title", title))
.andExpect(MockMvcResultMatchers.content()
.json(expect))
.andDo(MockMvcResultHandlers.print());
// mockbean 重置
}
@Test
public void bookServiceTest() {
String title = "java learning";
bookServiceMockBean(title);
Assertions.assertThat(bookService.queryByTitle("ss").getTitle()).isEqualTo(title);
}
/**
* Mock打桩
* @param title the title
*/
private void bookServiceMockBean(String title) {
Book book = new Book();
book.setAuthor("dax");
book.setPrice(78.56);
book.setReleaseTime(LocalDate.of(2018, 3, 22));
book.setTitle(title);
BDDMockito.given(bookService.queryByTitle(title)).willReturn(book);
}
}
Излишне говорить, что первые две аннотации тестового класса, третья аннотация@AutoConfigureMockMvc
Возможно, вы незнакомы. Это используется для запуска автоматической настройки тестов Mock MVC.
Затем мы пишем тестовый методbookApiTest()
тестироватьBookApi#getBook(String title)
интерфейс.
логикаMockMvc
Сделайте фиктивный запрос на получение и ожидайте, что результат будетexpect
Json и распечатайте соответствующий объект (указан на рис. 1 ниже). Выдает, если запрос не выполненjava.lang.AssertionError
ошибка, поместит ожидаемое значение (Expected
) и фактическое значение (отмечено на рис. 2 ниже). Если это так же, как ожидалось, появится только следующая цифра 1.
5. Пробная забивка
Существует очень распространенная ситуация, могут быть другие услуги в разработке вашего звонка, не завершают разработку, например, вы должны отправить интерфейс текстового сообщения, чтобы все еще пройти через форматы SMS-интерфейсы, но вам также нужно Тестовый короткий интерфейс сообщения. ты можешь пройти@MockBean
Создайте реализацию абстрактного интерфейса. ЛентаBookService
Например, если логика его класса реализации не определена, мы можем смоделировать логику bean-компонента, указав его входные параметры и соответствующие возвращаемые значения, или выбрать операцию маршрутизации в соответствии с определенной ситуацией (если входным параметром является A, то результат B, если C, то D). Эта симуляция также известна как тестовая заглушка. Здесь мы будем использоватьMockito
Сценарий тестирования описывается следующим образом:
- Определяет возвращаемое значение объекта укладки
- Определение количества способов вызова и вызов метода объекта укладки
- Укладка указанного объекта Выдает конкретное исключение
Как правило, следующие комбинации:
-
do/when:включают
doThrow(…).when(…)
/doReturn(…).when(…)
/doAnswer(…).when(…)
-
given/will:включают
given(…).willReturn(…)
/given(…).willAnswer(…)
-
when/then: включают
when(…).thenReturn(…)
/when(…).thenAnswer(…)
Другие легко понять, сосредоточьтесь на представленииAnswer
, Answer
Именно для решения операции маршрутизации, если входной параметр A, результат B, а если C, D. Далее, давайте попрактикуемся, в основном так же, как и в начале, просто замените его на@MockBean
затем используйтеMockito
Написать метод накладкиvoid bookServiceMockBean(String title)
, имитируя вышеописанноеBookServiceImpl
Класс реализации. Однако имитированный компонент автоматически сбрасывается после каждого теста. И не может использоваться для имитации поведения bean-компонентов, работающих во время обновления контекста приложения.
Затем внедрите этот метод в метод тестирования контроллера для тестирования.
6. Другие
Встроенныйassertj
Это также часто используемое утверждение, API очень дружественное, и оно также передается здесь.bookServiceTest()
Простая демонстрация
7. Резюме
В этой статье реализованы некоторые простые интеграционные тесты с поддержкой Spring Boot. Построение тестовой среды и написание тестового кода были осуществлены на практике, что в принципе может удовлетворить потребности ежедневной разработки и тестирования.Я думаю, вы можете многому научиться из этой статьи.
Соответствующий пояснительный код можно найти вgiteeПолучать.
тоже через меняличный блогПолучите больше галантереи, чтобы поделиться вовремя.
关注公众号:Felordcn获取更多资讯