Ответ
Для тестирования контроллеров Spring используется комбинация JUnit 5, Spring Test модуля и Mockito.
1. Тестирование слоя контроллера изолированно (@WebMvcTest):
Загружается только веб-слой контекста, все зависимости контроллера мокаются.
@WebMvcTest(UserController.class) // Загружаем только контроллер и MVC инфраструктуру
class UserControllerSliceTest {
@Autowired
private MockMvc mockMvc; // Главный инструмент для имитации запросов
@MockBean
private UserService userService; // Зависимость контроллера заменяется mock-объектом
@Test
void getUserById_ShouldReturnUser() throws Exception {
// Given
User mockUser = new User(1L, "Alice");
when(userService.findById(1L)).thenReturn(Optional.of(mockUser));
// When & Then
mockMvc.perform(get("/api/users/1")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1L))
.andExpect(jsonPath("$.name").value("Alice"));
verify(userService).findById(1L); // Проверяем вызов сервиса
}
}
2. Интеграционное тестирование (@SpringBootTest):
Загружается полный контекст приложения. Используется TestRestTemplate или WebTestClient для реальных HTTP-вызовов.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void getUserById_Integration() {
ResponseEntity<User> response = restTemplate.getForEntity("/api/users/1", User.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody().getName()).isNotNull();
}
}
Ключевые аннотации: @WebMvcTest (для срезов), @SpringBootTest (для интеграции), @MockBean (для моков в контексте Spring).