spring-boot - Unit Test for a Controller Advice without calling the controller
问题描述
I'm trying to write a unit test for a controllerAdvice, all the example I saw in the net are for an integration test, that's mean they are calling their main Rest controller and I dont want to do in that way. here is the test i'm trying to write :
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;
}
My issue is that the resolver.resolveException(this.servletRequest, this.servletResponse, null, ex) is returning null however it should not! any idea ?
解决方案
To resolve my issue I created a mocked controller that inject a given exception and throw it..
@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;
}
}
}
than I setup my unit test as follow :
@Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(cspControllerAdvice)
.build();
}
the test can be as follow :
@Test
public void given_MyException_return_Error_with_values() throws Exception {
controller.setException(new MyException(""));
assertExceptionHandler(....);
}
where
private void assertExceptionHandler(...) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(...);
}
推荐阅读
- javascript - 同一页面上的多个放置区会导致出现错误
- solr - 索引后 Solr 提交失败
- c# - 你如何从一个进程c#中调用另一个进程
- c++ - FormatDateTime - 整数算术溢出 C++
- ruby-on-rails - after_create 回调中的 ActiveJob::DeserializationError - 未找到记录
- boost - 将 boost program_options 添加为 git 子模块并使用其源构建可执行文件
- android - 在 Glide 的 getDrawable 方法中获取 NullPointerException
- angular - 单击按钮执行与 CTRL-V 事件相同的操作
- c# - 聆听 Class 上更改的某些值
- javascript - 如果参与者提供 n 个正确答案,则跳过其余时间线 (jspsych)