2015-04-01 116 views
0

我想對引發異常的控制器方法執行測試。該方法是這樣的:測試控制器拋出的異常

@RequestMapping("/do") 
public ResponseEntity doIt(@RequestBody Request request) throws Exception { 
    throw new NullPointerException(); 
} 

當我嘗試測試這種方法用下面的代碼部分,

mockMvc.perform(post("/do") 
       .contentType(MediaType.APPLICATION_JSON) 
       .content(JSON.toJson(request))) 

NestedServletException從Spring庫拋出。我如何測試NullPointerException而不是NestedServletException

+0

你正在做的POST和控制方法匹配GET。當您將其更改爲GET時,您將獲得NPE。 – NikolaB 2015-04-03 15:32:55

+0

@NikolaB空方法表示所有HTTP方法都映射到'doIt'。 http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-requestmapping – mtyurt 2015-04-03 15:38:02

+0

我不好嘗試捕獲NestedServletException並調用getRootCause()方法並查看返回的內容。 – NikolaB 2015-04-03 15:54:33

回答

1

我們的解決方案是一種解決方法:異常在advice中被捕獲,並且錯誤主體作爲HTTP響應返回。以下是如何模擬的工作原理:

MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller) 
         .setHandlerExceptionResolvers(withExceptionControllerAdvice()) 
         .build(); 

private ExceptionHandlerExceptionResolver withExceptionControllerAdvice() { 
    final ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() { 
     @Override 
     protected ServletInvocableHandlerMethod getExceptionHandlerMethod(final HandlerMethod handlerMethod, final Exception exception) { 
      Method method = new ExceptionHandlerMethodResolver(TestAdvice.class).resolveMethod(exception); 
      if (method != null) { 
       return new ServletInvocableHandlerMethod(new TestAdvice(), method); 
      } 
      return super.getExceptionHandlerMethod(handlerMethod, exception); 
     } 
    }; 
    exceptionResolver.afterPropertiesSet(); 
    return exceptionResolver; 
} 

諮詢類:

@ControllerAdvice 
public class TestAdvice { 
    @ExceptionHandler(Exception.class) 
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 
    public Object exceptionHandler(Exception e) { 
     return new HttpEntity<>(e.getMessage()); 
    } 
} 

後比,下面的測試方法,成功通過:

@Test 
public void testException 
    mockMvc.perform(post("/exception/path")) 
     .andExpect(status().is5xxServerError()) 
     .andExpect(content().string("Exception body")); 
}