middle
Как использовать TestRestTemplate для интеграционных тестов?
TestRestTemplate — обёртка над RestTemplate, предназначенная для интеграционных тестов с реальным HTTP-сервером. Работает только с webEnvironment = RANDOM_PORT или DEFINED_PORT.
Отличия от обычного RestTemplate
- Автоматически настраивает базовый URL (включая порт)
- Не бросает исключения при HTTP-ошибках (4xx, 5xx) — возвращает
ResponseEntity - Поддерживает Basic-аутентификацию из коробки
Полный пример интеграционного теста
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@LocalServerPort
private int port;
@Test
void shouldGetAllUsers() {
ResponseEntity<List<UserDto>> response = restTemplate.exchange(
"/api/users",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<UserDto>>() {}
);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody());
}
@Test
void shouldCreateUser() {
UserDto newUser = new UserDto("Иван", "ivan@example.com");
ResponseEntity<UserDto> response = restTemplate.postForEntity(
"/api/users",
newUser,
UserDto.class
);
assertEquals(HttpStatus.CREATED, response.getStatusCode());
assertNotNull(response.getBody().getId());
}
@Test
void shouldReturn404ForUnknownUser() {
ResponseEntity<String> response = restTemplate.getForEntity(
"/api/users/999",
String.class
);
// TestRestTemplate не бросает исключение — возвращает ответ с кодом ошибки
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
}
@Test
void shouldAccessProtectedEndpointWithAuth() {
TestRestTemplate authenticatedTemplate =
restTemplate.withBasicAuth("admin", "password");
ResponseEntity<String> response = authenticatedTemplate.getForEntity(
"/api/admin/dashboard",
String.class
);
assertEquals(HttpStatus.OK, response.getStatusCode());
}
}
На собеседовании: ключевой момент —
TestRestTemplateне бросает исключения на 4xx/5xx, в отличие отRestTemplate. Частая ошибка — использоватьTestRestTemplateсwebEnvironment = MOCK(он не будет работать без реального сервера).