Testing for 404 and Custom Exceptions in Spring MVC

We talked about creating custom 404 and other exceptions in Spring MVC, now we’ll look at our tests.

Testing for Contact Not Found Custom Exception

We’ll look at testing for our custom Contact Not Found exception first because it’s a bit more straightforward than how we test for a 404. The key to this test is adding the expected ContactNotFoundException to the @Test annotation. We have 10 contacts, so we throw the exception on our mock service for an Id of 11. At this point we perform a get /contact/11 on our mockMvc and expect to see our “error” view.

Testing for 404s

To test for a 404 we need to make our test know about the Exception Handlers in our @ControllerAdvice class with ExceptionHandlerExceptionResolver. Simply put, ExceptionHandlerExceptionResolver allows us to resolve exceptions through @ExceptionHandler methods.

There are a couple of ways to do this. One way is to add a ExceptionHandlerExceptionResolver createExceptionResolver() method like below. I don’t care for this approach and don’t use it, but it works.

private ExceptionHandlerExceptionResolver createExceptionResolver() {
ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
    protected ServletInvocableHandlerMethod 
	getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
	        Method method = new 
	        return new ServletInvocableHandlerMethod(new ExceptionController(), method);
	exceptionResolver.getMessageConverters().add(new MappingJackson2HttpMessageConverter());  
	return exceptionResolver;

Instead we’ll add our Exception Handlers in our @Before Setup(). We create a StaticApplicationContext and add our ExceptionController bean, then set the Exception Resolver in our mockMvc standaloneSetup. This approach is also better because we can add multiple @ControllerAdvice classes.

final ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver();
final StaticApplicationContext applicationContext = new StaticApplicationContext();
        new RootBeanDefinition(ExceptionController.class, null, null));
exceptionResolver.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

mockMvc = MockMvcBuilders.standaloneSetup(controller)

Everything is in place to write the test, which is now very straightforward.

You can find the complete source code for this post in the v0.1.5 branch of NixMash Spring on GitHub.