0Pricing
Java Academy · Урок

Срезы тестирования 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 — локальная установка не требуется.

Все уроки этого курса

  1. Параметризованные тесты с @CsvSource и @MethodSource
  2. Mockito: продвинутые возможности — перехватчики аргументов и шпионы
  3. Срезы тестирования Spring Boot: @WebMvcTest и @DataJpaTest
  4. Testcontainers: интеграционные тесты с реальной базой данных
← Назад к Java Academy