Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest
Используйте @WebMvcTest для изолированного тестирования контроллеров, а @DataJpaTest — для тестирования уровня репозиториев.
«Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest» — бесплатный урок Java Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Что такое тестовые срезы?
Тестовые срезы загружают только соответствующую часть контекста Spring для конкретного слоя. Они работают быстрее, чем @SpringBootTest, загружающий всё приложение, и изолируют проверяемый слой.
@WebMvcTest: Только слой контроллеров
@WebMvcTest(UserController.class) загружает только веб-слой: контроллеры, фильтры, конфигурацию безопасности и Jackson. Сервисы и репозитории необходимо имитировать с помощью @MockBean.
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired MockMvc mockMvc;
@MockBean UserService userService;
@Test
void get_user_returns_200() throws Exception {
given(userService.findById(1L)).willReturn(new UserDto(1L, "Alice"));
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}Формирование запросов MockMvc
Создавайте запросы с помощью MockMvcRequestBuilders. Задавайте заголовки, тип содержимого и тело запроса для тестов POST и PUT.
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"Bob","email":"bob@example.com"}"""))
.andExpect(status().isCreated())
.andExpect(header().exists("Location"));Проверка валидации в @WebMvcTest
Недействительные тела запросов вызывают MethodArgumentNotValidException. Проверьте статус 400 и тело ответа с ошибкой.
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"","email":"bad"}"""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors.name").exists());@DataJpaTest: Только слой репозиториев
@DataJpaTest загружает репозитории JPA, встроенную базу данных H2, Hibernate и TestEntityManager. Другие компоненты — сервисы и веб-слой — не загружаются.
@DataJpaTest
class UserRepositoryTest {
@Autowired UserRepository repo;
@Autowired TestEntityManager em;
@Test
void find_by_email() {
em.persist(new User("Alice", "alice@example.com"));
em.flush();
Optional<User> found = repo.findByEmail("alice@example.com");
assertTrue(found.isPresent());
}
}TestEntityManager
TestEntityManager оборачивает EntityManager и предоставляет вспомогательные методы: persist(), flush(), find(), persistAndFlush().
User saved = em.persistAndFlush(new User("Bob", "bob@example.com"));
assertNotNull(saved.getId());
em.clear(); // detach all to force a real DB read
User fromDb = repo.findById(saved.getId()).orElseThrow();
assertEquals("Bob", fromDb.getName());Откат в @DataJpaTest
Каждый тест по умолчанию выполняется в транзакции, которая откатывается после завершения теста. Данные не сохраняются между тестами, что обеспечивает их изоляцию без ручной очистки.
@DataJpaTest // each @Test is rolled back automatically
class OrderRepositoryTest {
@Test @Transactional
void count_orders_is_zero_by_default() {
assertEquals(0, orderRepo.count());
}
}Замена H2 на реальную базу данных в @DataJpaTest
Используйте @AutoConfigureTestDatabase(replace = Replace.NONE), чтобы запускать @DataJpaTest с реальной базой данных, настроенной в application.properties, вместо H2.
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class ProductRepositoryTest {
// Uses the configured PostgreSQL, not H2
}@JsonTest: Только сериализация JSON
@JsonTest загружает конфигурацию Jackson. Используйте JacksonTester, чтобы проверить, что объекты сериализуются и десериализуются ожидаемым образом.
@JsonTest
class UserDtoJsonTest {
@Autowired JacksonTester<UserDto> json;
@Test
void serializes_correctly() throws Exception {
UserDto dto = new UserDto(1L, "Alice", "alice@example.com");
assertThat(json.write(dto)).hasJsonPathStringValue("$.email");
}
}@RestClientTest: Слой REST-клиента
@RestClientTest проверяет HTTP-клиенты на основе RestTemplate или WebClient. Аннотация настраивает MockRestServiceServer для имитации ответов HTTP.
@RestClientTest(WeatherClient.class)
class WeatherClientTest {
@Autowired WeatherClient client;
@Autowired MockRestServiceServer server;
@Test
void fetches_weather() {
server.expect(requestTo("/api/weather")).andRespond(withSuccess("""{"temp":22}""", APPLICATION_JSON));
Weather w = client.getWeather("Istanbul");
assertEquals(22, w.getTemp());
}
}Объединение срезов с @Import
Срезы по замыслу исключают многие компоненты. Используйте @Import(SomeConfig.class), чтобы добавить конкретные классы конфигурации, необходимые срезу.
@WebMvcTest(UserController.class)
@Import(SecurityConfig.class) // load security for auth tests
class SecuredControllerTest { ... }Быстрая проверка
Какую базу данных @DataJpaTest использует по умолчанию?
Итоги
@WebMvcTest проверяет слой контроллеров с помощью MockMvc; имитируйте сервисы с помощью @MockBean. @DataJpaTest проверяет репозитории с помощью TestEntityManager и автоматически выполняет откат. Используйте Replace.NONE для реальной базы данных. Применяйте @JsonTest для сериализации, а @RestClientTest — для HTTP-клиентов.
Часто задаваемые вопросы
Урок «Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest» бесплатный?
Да — полный текст урока «Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest»?
Используйте @WebMvcTest для изолированного тестирования контроллеров, а @DataJpaTest — для тестирования уровня репозиториев. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Параметризованные тесты с @CsvSource и @MethodSource
- Mockito: продвинутые возможности — перехватчики аргументов и шпионы
- Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest
- Testcontainers: интеграционные тесты с реальной базой данных