2015-04-01 121 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")); 
}