JavaRush /Курсы /Модуль 5. Spring /Поддержка тестирования в Spring Boot

Поддержка тестирования в Spring Boot

Модуль 5. Spring
4 уровень , 9 лекция
Открыта

Давайте начнём с самого начала. Почему вообще нужно тестирование? Вы же не хотите, чтобы ваши пользователи натолкнулись на баги в продакшене, верно? Тестирование позволяет находить и устранять проблемы ещё до того, как они нанесут ущерб вашему приложению или вашей репутации. А Spring Boot предлагает удобные инструменты для упрощения этой задачи.

Spring Boot интегрируется с такими популярными библиотеками для тестирования, как JUnit и TestNG, и предоставляет дополнительные возможности через spring-boot-starter-test. Этот стартер включает всё необходимое для написания тестов:

  • JUnit 5 для написания тестов.
  • AssertJ для лаконичной проверки условий.
  • Hamcrest для мощных и наглядных выражений.
  • Mockito для создания заглушек (mock-объектов).
  • Spring Test — специальный модуль Spring, который помогает нам тестировать приложения в контексте Spring.

Установка тестовой среды

Для начала убедитесь, что в вашем pom.xml или build.gradle есть зависимость на spring-boot-starter-test.


<!-- pom.xml -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

Основы Spring Boot Test

Вместе с spring-boot-starter-test мы получаем мощный механизм для тестирования компонентов Spring-приложений: контроллеров, сервисов, репозиториев и даже всей системы целиком.

Аннотации Spring Boot Test

  • @SpringBootTest — запускает весь контекст приложения для проведения интеграционных тестов.
  • @MockBean — создаёт тестовые (mock) версии бинов. Полезно для изоляции тестируемой логики.
  • @WebMvcTest — поднимает только контекст Spring MVC, удобен для тестирования REST-контроллеров.
  • @DataJpaTest — создаёт контекст для тестирования репозиториев и работы с JPA.

Пример: допустим, у нас есть метод в сервисе, который возвращает список пользователей. Используя аннотации, мы можем протестировать его логику.


// UserService.java
@Service
public class UserService {
    public List<String> getUsers() {
        return Arrays.asList("Alice", "Bob", "Charlie");
    }
}


// UserServiceTest.java
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testGetUsers() {
        List<String> users = userService.getUsers();
        assertEquals(3, users.size());
        assertTrue(users.contains("Alice"));
    }
}

Практика тестирования

Давайте теперь посмотрим, как можно протестировать разные части нашего приложения.

Тестирование REST-контроллеров

Типичный контроллер:


// UserController.java
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping
    public List<String> getUsers() {
        return List.of("Alice", "Bob", "Charlie");
    }
}

Тестируем с помощью @WebMvcTest:


@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testGetUsers() throws Exception {
        mockMvc.perform(get("/users"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0]").value("Alice"))
                .andExpect(jsonPath("$[1]").value("Bob"));
    }
}

Что тут происходит?

  • Мы используем MockMvc для выполнения HTTP-запросов к нашему контроллеру.
  • Метод perform() отправляет GET-запрос на /users.
  • С помощью andExpect() мы проверяем статус ответа и содержимое JSON-массива.

Тестирование репозиториев

Давайте посмотрим на пример с использованием JPA. Мы пишем репозиторий для управления сущностью User.

Сущность:


// User.java
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    // getters & setters
}

Репозиторий:


// UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByName(String name);
}

Тест репозитория:


@DataJpaTest
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void testFindByName() {
        // Arrange
        User user = new User();
        user.setName("Alice");
        userRepository.save(user);

        // Act
        List<User> users = userRepository.findByName("Alice");

        // Assert
        assertEquals(1, users.size());
        assertEquals("Alice", users.get(0).getName());
    }
}

Пояснения:

  • Мы используем аннотацию @DataJpaTest, чтобы автоматически настроить встроенную базу данных (например, H2).
  • В методе Arrange мы добавляем тестовые данные в репозиторий.
  • В методе Act выполняется тестируемый метод.
  • В методе Assert проверяются результаты.

Интеграционное тестирование

Иногда нам нужно протестировать приложение целиком, включая все уровни — от контроллеров до базы данных. Для этого мы используем @SpringBootTest.

Пример:


@SpringBootTest
public class IntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testGetUsers() throws Exception {
        mockMvc.perform(get("/users"))
                .andExpect(status().isOk())
                .andExpect(content().string("[\"Alice\",\"Bob\",\"Charlie\"]"));
    }
}

Важные моменты

1. Использование H2 для тестирования.

Spring Boot автоматически подключает H2 Database в тестах, если вы используете JPA. Это позволяет тестировать базу данных без необходимости поднимать реальный сервер.

2. Использование mock-объектов с Mockito.

Mockito позволяет "мокать" зависимости, чтобы изолировать тестируемый код. Например:


@MockBean
private UserService userService;

@Test
public void testMockedService() {
    when(userService.getUsers()).thenReturn(List.of("MockedUser"));

    // Your test code here
}

Преимущества тестирования с Spring Boot

  • Удобная интеграция. Все инструменты интегрированы, вам не нужно ничего настраивать вручную.
  • Эффективность. Тесты запускаются быстро, даже при использовании встроенной базы данных.
  • Надёжность. Хорошее покрытие тестами позволяет избежать неожиданных проблем в продакшене.

Теперь вы вооружены всеми основными знаниями, необходимыми для тестирования Spring Boot приложений. Помните, любые изменения в коде заслуживают проверки тестами. Тестируйте всё, что движется (и даже то, что ещё нет). И, как говорится, "лучше маленький тест, чем большое извинение перед заказчиком".

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ