我想对抛出异常的控制器方法执行测试。方法是这样的:
@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)))
从Spring库中抛出 NestedServletException
。如何测试NullPointerException
而不是NestedServletException
?
答案 0 :(得分:1)
我们的解决方案是一种解决方法:在建议中捕获异常,并将错误体作为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"));
}
答案 1 :(得分:1)
更简单的方法是将@ExceptionHandler
注入到Spring Test Context中,或者在MockMvc.perform()
之前的.andExpect()
中抛出异常。
@ContextConfiguration(classes = { My_ExceptionHandler_AreHere.class })
@AutoConfigureMockMvc
public class Test {
@Autowired
private MockMvc mvc;
@Test
public void test() {
RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/update")
.param("branchId", "13000")
.param("triggerId", "1");
MvcResult mvcResult = mvc.perform(requestBuilder)
.andExpect(MockMvcResultMatchers.status().is4xxClientError())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(__ -> Assert.assertThat(
__.getResolvedException(),
CoreMatchers.instanceOf(SecurityException.class)))
.andReturn();
}
这样MvcResult.getResolvedException()
保留@Controller
的例外!