복붙노트

[SPRING] Spring MVC 테스트의 빈 예외 바디

SPRING

Spring MVC 테스트의 빈 예외 바디

MockMvc가 응답 본문에 예외 메시지를 포함 시키려고 할 때 문제가 있습니다. 다음과 같이 컨트롤러가 있습니다.

@RequestMapping("/user/new")
public AbstractResponse create(@Valid NewUserParameters params, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) throw BadRequestException.of(bindingResult);
    // ...
}

여기서 BadRequestException은 sth가 다음과 같이 보입니다.

@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "bad request")
public class BadRequestException extends IllegalArgumentException {

    public BadRequestException(String cause) { super(cause); }

    public static BadRequestException of(BindingResult bindingResult) { /* ... */ }

}

/ user / new controller에 대해 다음 테스트를 실행합니다.

@Test
public void testUserNew() throws Exception {
    getMockMvc().perform(post("/user/new")
            .param("username", username)
            .param("password", password))
            .andDo(print())
            .andExpect(status().isOk());
}

그러면 다음 출력이 인쇄됩니다.

  Resolved Exception:
                Type = controller.exception.BadRequestException

        ModelAndView:
           View name = null
                View = null
               Model = null

            FlashMap:

MockHttpServletResponse:
              Status = 400
       Error message = bad request
             Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY]}
        Content type = null
                Body = 
       Forwarded URL = null
      Redirected URL = null
             Cookies = []

누구나 print () 출력에서 ​​Body가없는 이유에 대해 누구나 알고 있습니까?

편집 : 나는 모든 사용자 지정 예외 처리기를 사용하지 않고 코드를 서버를 실행할 때 예상대로 작동합니다. 즉, 응용 프로그램을 실행하고 서버에 동일한 요청을하면 되돌아갑니다.

{"timestamp":1423076185822,
 "status":400,
 "error":"Bad Request",
 "exception":"controller.exception.BadRequestException",
 "message":"binding failed for field(s): password, username, username",
 "path":"/user/new"}

예상대로 따라서 MockMvc에 문제가 있습니다. 정규 응용 프로그램 서버의 기본 예외 처리기가 예상대로 작동하는 반면, 여하튼 예외의 메시지 필드를 캡처하지 못합니다.

해결법

  1. ==============================

    1.문제 티켓을 열어 본문의 오류 메시지가 Servlet 컨테이너 수준에서 오류 매핑을 구성하고 Spring MVC 테스트가 모의 서블릿 요청 / 응답과 함께 실행되기 때문에 Spring Boot가 처리했다고 들었습니다. 그러한 오류 매핑은 없습니다. 더 나아가 적어도 하나의 @WebIntegrationTest를 만들고 내 컨트롤러 로직을위한 Spring MVC Test에 충실하라고 권했다.

    문제 티켓을 열어 본문의 오류 메시지가 Servlet 컨테이너 수준에서 오류 매핑을 구성하고 Spring MVC 테스트가 모의 서블릿 요청 / 응답과 함께 실행되기 때문에 Spring Boot가 처리했다고 들었습니다. 그러한 오류 매핑은 없습니다. 더 나아가 적어도 하나의 @WebIntegrationTest를 만들고 내 컨트롤러 로직을위한 Spring MVC Test에 충실하라고 권했다.

    결국, 나는 내 자신 만의 예외 처리기를 가지고 MockMvc를 사용하기로 결정했다.

    @ControllerAdvice
    public class CustomExceptionHandler {
    
        @ExceptionHandler(Throwable.class)
        public @ResponseBody
        ExceptionResponse handle(HttpServletResponse response, Throwable throwable) {
            HttpStatus status = Optional
                    .ofNullable(AnnotationUtils.getAnnotation(throwable.getClass(), ResponseStatus.class))
                    .map(ResponseStatus::value)
                    .orElse(HttpStatus.INTERNAL_SERVER_ERROR);
            response.setStatus(status.value());
            return new ExceptionResponse(throwable.getMessage());
        }
    
    }
    
    @Data
    public class ExceptionResponse extends AbstractResponse {
    
        private final long timestamp = System.currentTimeMillis();
    
        private final String message;
    
        @JsonCreator
        public ExceptionResponse(String message) {
            checkNotNull(message, "message == NULL");
            this.message = message;
        }
    
    }
    
  2. ==============================

    2.이는 예외를 처리하지 않았거나 몸을 실제로 비워 두었다는 것을 의미합니다. 예외를 처리하려면 컨트롤러에 오류 처리기를 추가하거나

    이는 예외를 처리하지 않았거나 몸을 실제로 비워 두었다는 것을 의미합니다. 예외를 처리하려면 컨트롤러에 오류 처리기를 추가하거나

    @ExceptionHandler
    public @ResponseBody String handle(BadRequestException e) {
        return "I'm the body";
    }
    

    3.2 이상이면 전역 오류 처리기를 사용하십시오.

    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        @ExceptionHandler
        public @ResponseBody String handleBadRequestException(BadRequestException ex) {
            return "I'm the body";
        }
    }
    

    이 몸체가 채워지면 오류 메시지가 표시됩니다.

  3. from https://stackoverflow.com/questions/28324994/empty-exception-body-in-spring-mvc-test by cc-by-sa and MIT license