1

스프링 부트 애플리케이션이 있고 통합 테스트를 통해 내 REST 컨트롤러를 다루고 싶습니다. 내가 그 끝점을 테스트 할 테스트 케이스 중 하나에서스프링 부트 테스트 : REST 컨트롤러의 예외

@RestController 
@RequestMapping("/tools/port-scan") 
public class PortScanController { 
    private final PortScanService service; 

    public PortScanController(final PortScanService portScanService) { 
     service = portScanService; 
    } 

    @GetMapping("") 
    public final PortScanInfo getInfo(
      @RequestParam("address") final String address, 
      @RequestParam(name = "port") final int port) 
      throws InetAddressException, IOException { 
     return service.scanPort(address, port); 
    } 
} 

어떤 상황에서 예외가 발생합니다 : 여기 내 컨트롤러입니다. 다음은 테스트 클래스입니다.

@RunWith(SpringRunner.class) 
@WebMvcTest(PortScanController.class) 
public class PortScanControllerIT { 
    @Autowired 
    private MockMvc mvc; 

    private static final String PORT_SCAN_URL = "/tools/port-scan"; 

    @Test 
    public void testLocalAddress() throws Exception { 
     mvc.perform(get(PORT_SCAN_URL).param("address", "192.168.1.100").param("port", "53")).andExpect(status().isInternalServerError()); 
    } 
} 

어떻게해야할까요? 원래 InetAddressException이기 때문에 @Test 주석에서 예상 예외를 지정할 수 없습니다

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.handytools.webapi.exceptions.InetAddressException: Site local IP is not supported 

: 현재 구현은 내가 테스트를 시작할 때, 나는 수신 및 오류 (PortScanController.getInfo에서 발생)하고 InetAddressException을 처리하지 않습니다 NestedServletException으로 랩됩니다.

당신은 예외 핸들러를 정의 할 수

답변

2

@ExceptionHandler(InetAddressException.class) 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
@ResponseBody 
public Response handledInvalidAddressException(InetAddressException e) 
{ 
    log e 
    return getValidationErrorResponse(e); 
} 

다음 테스트에서 당신은 (즉, InetAddressException를) 랩 된 예외를 테스트하기 위해, 당신은의 JUnit을 만들 수 있습니다에서

mvc.perform(get(PORT_SCAN_URL) 
    .param("address", "192.168.1.100") 
    .param("port", "53")) 
    .andExpect(status().isBadRequest()) 
    .andExpect(jsonPath("$.response").exists()) 
    .andExpect(jsonPath("$.response.code", is(400))) 
    .andExpect(jsonPath("$.response.errors[0].message", is("Site local IP is not supported"))); 
+0

감사합니다. Borys. MockMvc 인스턴스를 자동 구성했음을 고려하여 어떻게 할 수 있습니까? – DavyJohnes

+0

나는 당신의 테스트가 아닌 당신의 어플리케이션을위한 예외 핸들러를 의미했다. 애플리케이션이'@ExceptionHandler (InetAddressException.class)'를 선언 한 다음 오류를 설명하는 메시지와 함께 400 또는 503 상태 코드로 응답하면 테스트는 응답으로 예상 상태 코드와 예상 오류 메시지를 찾습니다. – borowis

+0

당신이 얻는 것은 실제로 유효성 검사 오류이므로 오류 메시지와 함께 400 코드가 적절하다고 보입니다 – borowis

4

을 할 수 ExpectedException 클래스를 사용하고 expectMessage() (실제 원인을 포함하는 NestedServletExceptiongetMessage()을 받음)을 설정하면 다음 코드를 참조 할 수 있습니다.

@Rule 
public ExpectedException inetAddressExceptionRule = ExpectedException.none(); 

@Test 
public void testLocalAddress() { 

    //Set the message exactly as returned by NestedServletException 
    inetAddressExceptionRule.expectMessage("Request processing failed; nested exception is com.handytools.webapi.exceptions.InetAddressException: Site local IP is not supported"); 

    //or you can check below for actual cause 
    inetAddressExceptionRule.expectCause(org.hamcrest.Matchers.any(InetAddressException.class)) 

    //code for throwing InetAddressException here (wrapped by Spring's NestedServletException) 
} 

당신은 여기에 ExpectedException API를 참조 할 수 있습니다 :

http://junit.org/junit4/javadoc/4.12/org/junit/rules/ExpectedException.html

+0

불행히도 작동하지 않습니다. 내 질문에 언급했듯이 원래 예외 NestedServletException 래핑됩니다. – DavyJohnes

+0

이미 완료했습니다. 작동하지 않습니다. jUnit은이 예외를 처리하지 않습니다. – DavyJohnes

+0

내 코드를보고 ExpectedException 규칙을 작성하십시오. – developer

6

봄 부팅 테스트 패키지가 발생 예외를 확인하는 매우 편리한 방법이 AssertJ와 함께 제공됩니다.

는 원인을 확인하려면 다음

@Test 
public void shouldThrowException() { 
    assertThatThrownBy(() -> methodThrowingException()).hasCause(InetAddressException .class); 
} 

관심을 가질 몇 가지 방법도 있습니다 내가 docs의 모양을 가진 것이 좋습니다..

관련 문제