Рубрики
Без рубрики

Тестирование исключений с помощью Spring MockMvc

Узнайте, как создавать исключения контроллера модульного тестирования с помощью Spring MockMvc.

Автор оригинала: baeldung.

1. Обзор

В этой короткой статье мы рассмотрим, как исключения должны создаваться в наших контроллерах и как протестировать эти исключения с помощью Spring MockMvc.

2. Создание исключений в контроллерах

Давайте начнем изучать как запустить исключение из контроллера .

Мы можем думать об услугах, которые мы предоставляем с контроллера, так же, как если бы они были обычными функциями Java:

@GetMapping("/exception/throw")
public void getException() throws Exception {
    throw new Exception("error");
}

Теперь давайте посмотрим, что произойдет, когда мы вызовем эту службу. Во-первых, мы заметим, что код ответа службы равен 500, что означает внутреннюю ошибку сервера.

Во-вторых, мы получаем такой ответный орган, как этот:

{
    "timestamp": 1592074599854,
    "status": 500,
    "error": "Internal Server Error",
    "message": "No message available",
    "trace": "java.lang.Exception
              at com.baeldung.controllers.ExceptionController.getException(ExceptionController.java:26)
              ..."
}

В заключение, когда мы создаем исключение из RestController , ответ службы автоматически сопоставляется с кодом ответа 500, а трассировка стека исключения включается в тело ответа.

3. Сопоставление исключений с кодами ответов HTTP

Теперь мы собираемся узнать как сопоставлять наши исключения с различными кодами ответов кроме 500.

Для достижения этой цели мы собираемся создать пользовательские исключения и использовать аннотацию ResponseStatus , предоставленную Spring. Давайте создадим эти пользовательские исключения:

@ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadArgumentsException extends RuntimeException {

    public BadArgumentsException(String message) {
        super(message);
    }
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class InternalException extends RuntimeException {

    public InternalException(String message) {
        super(message);
    }
}
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {

    public ResourceNotFoundException(String message) {
        super(message);
    }
}

Второй и последний шаг-создать простую службу в нашем контроллере, чтобы создавать эти исключения:

@GetMapping("/exception/{exception_id}")
public void getSpecificException(@PathVariable("exception_id") String pException) {
    if("not_found".equals(pException)) {
        throw new ResourceNotFoundException("resource not found");
    }
    else if("bad_arguments".equals(pException)) {
        throw new BadArgumentsException("bad arguments");
    }
    else {
        throw new InternalException("internal error");
    }
}

Теперь давайте посмотрим различные ответы службы на различные исключения, которые мы сопоставили:

  • Для not_found мы получаем код ответа 404
  • Учитывая значение bad_arguments , мы получаем код ответа 400
  • Для любого другого значения мы по-прежнему получаем 500 в качестве кода ответа

Помимо кодов ответов, мы получим текст в том же формате, что и текст ответа, полученный в предыдущем разделе.

4. Тестирование Наших Контроллеров

Наконец, мы увидим как проверить, что наш контроллер выдает правильные исключения .

Первым шагом является создание тестового класса и создание экземпляра MockMvc :

@Autowired
private MockMvc mvc;

Далее давайте создадим тестовые примеры для каждого из значений, которые может получить наш сервис:

@Test
public void givenNotFound_whenGetSpecificException_thenNotFoundCode() throws Exception {
    String exceptionParam = "not_found";

    mvc.perform(get("/exception/{exception_id}", exceptionParam)
      .contentType(MediaType.APPLICATION_JSON))
      .andExpect(status().isNotFound())
      .andExpect(result -> assertTrue(result.getResolvedException() instanceof ResourceNotFoundException))
      .andExpect(result -> assertEquals("resource not found", result.getResolvedException().getMessage()));
}

@Test
public void givenBadArguments_whenGetSpecificException_thenBadRequest() throws Exception {
    String exceptionParam = "bad_arguments";

    mvc.perform(get("/exception/{exception_id}", exceptionParam)
      .contentType(MediaType.APPLICATION_JSON))
      .andExpect(status().isBadRequest())
      .andExpect(result -> assertTrue(result.getResolvedException() instanceof BadArgumentsException))
      .andExpect(result -> assertEquals("bad arguments", result.getResolvedException().getMessage()));
}

@Test
public void givenOther_whenGetSpecificException_thenInternalServerError() throws Exception {
    String exceptionParam = "dummy";

    mvc.perform(get("/exception/{exception_id}", exceptionParam)
      .contentType(MediaType.APPLICATION_JSON))
      .andExpect(status().isInternalServerError())
      .andExpect(result -> assertTrue(result.getResolvedException() instanceof InternalException))
      .andExpect(result -> assertEquals("internal error", result.getResolvedException().getMessage()));
}

С помощью этих тестов мы проверяем, что код ответа, тип вызванного исключения и сообщения об этих исключениях являются ожидаемыми для каждого из значений.

5. Заключение

В этом уроке мы узнали, как обрабатывать исключения в нашем Spring RestController s и как проверить, что каждая открытая служба выдает ожидаемые исключения.

Как всегда, полный исходный код статьи доступен в GitHub .