Testing @RestController with @ControllerAdvice

java, junit, spring

Solution

I'm not sure if this is the best solution for this (I'd like to hear from another one), but this is how I fix this exactly issue you are facing:

Add this line to your `createExceptionResolver()`:

exceptionResolver.getMessageConverters().add(
        new MappingJackson2HttpMessageConverter());

Something like this:

private ExceptionHandlerExceptionResolver createExceptionResolver() {
    ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
        @Override
        protected ServletInvocableHandlerMethod getExceptionHandlerMethod(
            HandlerMethod handlerMethod, Exception exception) {
            Method method = new ExceptionHandlerMethodResolver(
                    MyAppExceptionHandler.class).resolveMethod(exception);
            return new ServletInvocableHandlerMethod(
                new MyAppExceptionHandler(), method);
        }
    };
    exceptionResolver.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    exceptionResolver.afterPropertiesSet();
    return exceptionResolver;
}

For some reason that I don't know, Spring was not loading my MappingJackson2HttpMessageConverter. That line fixed my problem.

Problem

My problem is connected with testing Spring @RestController which is also using @ControllerAdvice with @ExceptionHandler. Here is the code: @ControllerAdvice class: ``` @ControllerAdvice public class MyAppExceptionHandler { @ExceptionHandler({ NoSuchEntityException.class }) @ResponseStatus(value = HttpStatus.NOT_FOUND) public @ResponseBody ErrorDTO handleNotFoundException(Exception ex) throws IOException { return new ErrorDTO.Builder().setStatus(HttpStatus.NOT_FOUND) .setCause(ex.getClass().getName()) .setThrowable(ex).build(); } } ``` When using it in application everything works fine - perfectly getting 404 response with JSON explanation, but when trying to use it during tests - bad things happen. My test class: ``` @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { WebConfig.class }) @WebAppConfiguration public class SomeTest { @Mock private SomeService service; @InjectMocks private SomeController controller; private MockMvc mvc; private ExceptionHandlerExceptionResolver createExceptionResolver() { ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() { @Override protected ServletInvocableHandlerMethod getExceptionHandlerMethod( HandlerMethod handlerMethod, Exception exception) { Method method = new ExceptionHandlerMethodResolver( MyAppExceptionHandler.class).resolveMethod(exception); return new ServletInvocableHandlerMethod( new MyAppExceptionHandler(), method); } }; exceptionResolver.afterPropertiesSet(); return exceptionResolver; } @Before public void setup() { MockitoAnnotations.initMocks(this); mvc = MockMvcBuilders.standaloneSetup(controller) .setHandlerExceptionResolvers(createExceptionResolver()) .build(); } @Test public void thatExceptionHappens() throws Exception { when(service.get(10)).thenThrow(new NoSuchEntityException(Some.class, 10)); mvc.perform(get("/api/some/10")).andExpect(status().isNotFound()); } } ``` When trying to run it: ``` 2014-07-15 19:35:01.376 [main] ERROR com.package.SomeTest$1 - Failed to invoke @ExceptionHandler method: public com.package.ErrorDTO com.package.MyAppExceptionHandler.handleNotFoundException(java.lang.Exception) throws java.io.IOException org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation ``` I think that probably MappingJackson2HttpMessageConverter is not being loaded during testing mine @ExceptionHandler (however it is configured in WebConfig.class and when trying to perform typical test - one not throwing any exception - everything works fine). Thanks in advance for your help.

Original source