SpringBoot тестирует пользовательский контроллер ошибок

Следуя совету отсюда Spring Boot Remove Whitelabel Error Page, я создал собственный контроллер ошибок, чтобы возвращать собственный ответ об ошибке в формате json, который похоже

@RestController
public class CustomErrorController implements ErrorController {

private static final String PATH = "/error";

@Value("${spring.debug:false}")
private boolean debug;

@Autowired
private ErrorAttributes errorAttributes;

  @RequestMapping(value = PATH)
  ErrorJson error(HttpServletRequest request, HttpServletResponse response) {
    return new ErrorJson(response.getStatus(), getErrorAttributes(request, debug));
  }

  private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
    RequestAttributes requestAttributes = new ServletRequestAttributes(request);
    return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
  }

  @Override
  public String getErrorPath() {
    return PATH;
  }

}

Где CustomErrorController реализует ErrorController, а ErrorJson — это просто класс для форматирования ответа на ошибку json.

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

{
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "timeStamp": "Thu Jun 29 14:55:44 PDT 2017",
  "trace": null
}

Мой тест в настоящее время выглядит так

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class CustomErrorControllerTest {

    @Autowired
    private MockMvc mockMvc;


    @Test
    public void invalidURLGet() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/foo"))
                .andExpect(status().is(404))
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andReturn();

    }


}

Я получаю ответ об ошибке со статусом 404, но тело содержимого равно null, с MockHttpServletResponse как:

MockHttpServletResponse:
           Status = 404
    Error message = null
          Headers = {X-Application-Context=[application:development:-1]}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Итак, у меня есть 2 вопроса:

  1. Почему тело содержимого равно null. MockMvc не может найти файл CustomErrorController.
  2. Я неправильно тестирую поведение ошибки. Если да, то как я могу проверить пользовательский ответ об ошибке?

person harshs08    schedule 29.06.2017    source источник


Ответы (1)


Вы можете получить больше с помощью TestRestTemplate вместо этого. Это позволит вам не только делать соответствующие вызовы URI, но также даст вам возможность сериализовать ваш ответ в фактический объект, который он возвращает, чтобы убедиться, что ваше тело и другие элементы действительно присутствуют.

Краткий пример:

// Elsewhere...
@Autowired
private TestRestTemplate template;

// In your tests...
ErrorJson result = template.getForObject("/error", ErrorJson.class);

// Inspect the result!
person Makoto    schedule 29.06.2017
comment
Пытался использовать TestRestTemplate, но теперь получаю следующую ошибку. *************************** ПРИЛОЖЕНИЕ НЕ ЗАПУЩЕНО ******************* ******** Описание: Не удалось запустить коннектор Tomcat, настроенный на прослушивание порта 0. Возможно, порт уже используется или разъем может быть неправильно настроен. Действие: проверьте конфигурацию соединителя, определите и остановите любой процесс, прослушивающий порт 0, или настройте это приложение для прослушивания другого порта. - person harshs08; 30.06.2017
comment
Итак... вы уверены, что выбрали случайный порт для своих тестов? Как это сделать описано в ссылке, которую я вам дал. - person Makoto; 30.06.2017
comment
Да, используя @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) - person harshs08; 30.06.2017