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

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

Открыта

Давайте начнём с самого начала. Почему вообще нужно тестирование? Вы же не хотите, чтобы ваши пользователи натолкнулись на баги в продакшене, верно? Тестирование позволяет находить и устранять проблемы ещё до того, как они нанесут ущерб вашему приложению или вашей репутации. А 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 приложений. Помните, любые изменения в коде заслуживают проверки тестами. Тестируйте всё, что движется (и даже то, что ещё нет). И, как говорится, "лучше маленький тест, чем большое извинение перед заказчиком".

Комментарии
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
У этой страницы еще нет ни одного комментария