在不调用控制器的情况下对控制器建议进行单元测试
Unit Test for a Controller Advice without calling the controller
我正在尝试为 controllerAdvice 编写单元测试,我在网上看到的所有示例都是针对集成测试的,这意味着他们正在调用他们的主要 Rest 控制器,而我不想那样做.
这是我要写的测试:
public class ExceptionTest {
private MockHttpServletRequest servletRequest;
private MockHttpServletResponse servletResponse;
@Before
public void setup() {
this.servletRequest = new MockHttpServletRequest("GET", "/");
this.servletResponse = new MockHttpServletResponse();
}
@Test
public void controllerAdviceExceptionHandlerExceptionResolverTest () throws UnsupportedEncodingException {
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
ctx.registerSingleton("exceptionHandler", MyControllerAdvice.class);
ctx.refresh();
ExceptionHandlerExceptionResolver resolver = createExceptionResolver();
resolver.setApplicationContext(ctx);
ServletRequestBindingException ex = new ServletRequestBindingException("message");
Assert.assertNotNull(resolver.resolveException(this.servletRequest, this.servletResponse, null, ex));
}
private ExceptionHandlerExceptionResolver createExceptionResolver() {
ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
Method method = new ExceptionHandlerMethodResolver(MyControllerAdvice.class).resolveMethod(exception);
return new ServletInvocableHandlerMethod(new MyControllerAdvice(), method);
}
};
exceptionResolver.afterPropertiesSet();
return exceptionResolver;
}
我的问题是 resolver.resolveException(this.servletRequest, this.servletResponse, null, ex) 返回 null 但它不应该返回 null!有什么想法吗?
为了解决我的问题,我创建了一个模拟控制器,它注入一个给定的异常并抛出它..
@Controller
class MockedTestController {
private Throwable exception;
void setException(Throwable exception) {
this.exception = exception;
}
@GetMapping
public void handle() throws Throwable {
if (this.exception != null) {
throw this.exception;
}
}
}
我的单元测试设置如下:
@Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(cspControllerAdvice)
.build();
}
测试可以如下:
@Test
public void given_MyException_return_Error_with_values() throws Exception {
controller.setException(new MyException(""));
assertExceptionHandler(....);
}
其中
private void assertExceptionHandler(...) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(...);
}
我正在尝试为 controllerAdvice 编写单元测试,我在网上看到的所有示例都是针对集成测试的,这意味着他们正在调用他们的主要 Rest 控制器,而我不想那样做. 这是我要写的测试:
public class ExceptionTest {
private MockHttpServletRequest servletRequest;
private MockHttpServletResponse servletResponse;
@Before
public void setup() {
this.servletRequest = new MockHttpServletRequest("GET", "/");
this.servletResponse = new MockHttpServletResponse();
}
@Test
public void controllerAdviceExceptionHandlerExceptionResolverTest () throws UnsupportedEncodingException {
StaticWebApplicationContext ctx = new StaticWebApplicationContext();
ctx.registerSingleton("exceptionHandler", MyControllerAdvice.class);
ctx.refresh();
ExceptionHandlerExceptionResolver resolver = createExceptionResolver();
resolver.setApplicationContext(ctx);
ServletRequestBindingException ex = new ServletRequestBindingException("message");
Assert.assertNotNull(resolver.resolveException(this.servletRequest, this.servletResponse, null, ex));
}
private ExceptionHandlerExceptionResolver createExceptionResolver() {
ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
Method method = new ExceptionHandlerMethodResolver(MyControllerAdvice.class).resolveMethod(exception);
return new ServletInvocableHandlerMethod(new MyControllerAdvice(), method);
}
};
exceptionResolver.afterPropertiesSet();
return exceptionResolver;
}
我的问题是 resolver.resolveException(this.servletRequest, this.servletResponse, null, ex) 返回 null 但它不应该返回 null!有什么想法吗?
为了解决我的问题,我创建了一个模拟控制器,它注入一个给定的异常并抛出它..
@Controller
class MockedTestController {
private Throwable exception;
void setException(Throwable exception) {
this.exception = exception;
}
@GetMapping
public void handle() throws Throwable {
if (this.exception != null) {
throw this.exception;
}
}
}
我的单元测试设置如下:
@Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(cspControllerAdvice)
.build();
}
测试可以如下:
@Test
public void given_MyException_return_Error_with_values() throws Exception {
controller.setException(new MyException(""));
assertExceptionHandler(....);
}
其中
private void assertExceptionHandler(...) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(...);
}