Gymterview
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 (он не будет работать без реального сервера).