springmockitomockmvccontroller-advice

How to test exceptions handling in @ControllerAdvice


I currently have two ControllerAdvice in my application, I'm supposed to merge them into one. But I need to test them before and after the merge, test the exception and the object that the controller return me.

I'm trying to make a jUnit test with Mockito but it seems impossible to test the exceptions without any context, without a controller, etc ...

Does anyone know how can I proceed to achieve what I'm trying to do ?

I also try to throw manually an exception but obviously it wasn't catched by the ControllerAdvice.

So basically here is what i'm trying to do: Manually throw an exception This exception is handled by my ControllerAdvice Check the returned object (code & message)

Here is a sample of code I have:

@Before
public void setup() {
  ...
    mockMvc = MockMvcBuilders.standaloneSetup(getController())
                .setControllerAdvice(new GlobalControllerExceptionHandler())
                .setCustomArgumentResolvers(resolver, resolver_0, resolver_1)
                .setHandlerExceptionResolvers(exceptionResolver).build();
}


@Controller
@RequestMapping("/tests")
public static class RestProcessingExceptionThrowingController {

    @RequestMapping(value = "/exception", method = GET)
    public @ResponseBody String find() {
        throw new EntityNotFoundException();
    }
}

@Test
public void testHandleException() throws Exception {
    mockMvc.perform(get("/tests/exception"))
            .andExpect(new ResultMatcher() {


                @Override
                public void match(MvcResult result) throws Exception {
                    result.getResponse().getContentAsString().contains("global_error_test");
                }
            })
            .andExpect(status().isNotFound());
}

I have the good status code at the end but it doesn't use my ControllerAdvice (I try with the debugger)


Solution

  • You can just call handler method directly

    @ControllerAdvice
    
    MyAdvice{
    
        @ExceptionHandeler(listOfExxcetpions)
        public ResponseEntity someOfMyExceptionsHandler(Exception e){
           .....
         }  
    
    }
    

    and in test

    MuTest{
    private MyAdvice advice=new MyAdvice();
    
    @Test
    public void oneOfTests(){
        Exception e=new SomeSortOfExceptionToTest();
        resp=advice.someOfMyExceptionsHandler(e)
        assertThat(resp).....dostuff;
    }
    
    }
    

    If you want to test how spring integrates with your handlers - if your annotations are correct, ordering serialization etc - well that will be an integration test and you have to boot up test context - then you can throw exceptions directly from controller methods.