Gymterview
middle

Как тестировать Spring-приложения? Какие основные аннотации для тестирования?

Spring Boot предоставляет инструментарий для тестирования на всех уровнях: от unit-тестов без контекста до полноценных интеграционных тестов.

Основные аннотации

Аннотация Что поднимает Скорость
(без Spring) Ничего, чистый Mockito Быстро
@WebMvcTest Только веб-слой (контроллеры) Быстро
@DataJpaTest Только JPA-слой (репозитории) Средне
@SpringBootTest Полный контекст приложения Медленно

1. Unit-тесты (без Spring-контекста)

Пример
class UserServiceTest {
    @Mock private UserRepository userRepository;
    private UserService userService;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
        userService = new UserService(userRepository);
    }

    @Test
    void shouldFindUserById() {
        when(userRepository.findById(1L)).thenReturn(Optional.of(new User(1L, "Ivan")));
        UserDto result = userService.findById(1L);
        assertThat(result.getName()).isEqualTo("Ivan");
    }
}

2. @WebMvcTest – тест контроллера

Пример
@WebMvcTest(UserController.class)
class UserControllerTest {
    @Autowired private MockMvc mockMvc;
    @MockBean private UserService userService; // Spring-мок в контексте

    @Test
    void shouldReturnUser() throws Exception {
        when(userService.findById(1L)).thenReturn(new UserDto(1L, "Ivan", "ivan@mail.ru"));
        mockMvc.perform(get("/api/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("Ivan"));
    }
}

3. @DataJpaTest – тест репозитория

Пример
@DataJpaTest
@ActiveProfiles("test")
class UserRepositoryTest {
    @Autowired private UserRepository userRepository;
    @Autowired private TestEntityManager entityManager;

    @Test
    void shouldFindByEmail() {
        entityManager.persistAndFlush(new User("Ivan", "ivan@mail.ru"));
        Optional<User> found = userRepository.findByEmail("ivan@mail.ru");
        assertThat(found).isPresent();
    }
}

4. @SpringBootTest – интеграционный тест

Пример
@SpringBootTest
@ActiveProfiles("test")
class UserServiceIntegrationTest {
    @Autowired private UserService userService;

    @Test @Transactional
    void shouldCreateUser() {
        UserDto result = userService.create(new CreateUserRequest("Ivan", "ivan@mail.ru"));
        assertThat(result.getId()).isNotNull();
    }
}

На собеседовании: покажите знание «слайс-тестов» и когда что использовать. Частая ошибка – использовать @SpringBootTest для всех тестов (медленно). Также – путать @Mock (Mockito) и @MockBean (Spring): @Mock не подменяет бин в контексте.