2013-05-21 18 views
28

Ho il seguente controller semplice per raccogliere eventuali eccezioni impreviste:Metodo di prova Spring MVC @ExceptionHandler con Spring MVC prova

@ControllerAdvice 
public class ExceptionController { 

    @ExceptionHandler(Throwable.class) 
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) 
    @ResponseBody 
    public ResponseEntity handleException(Throwable ex) { 
     return ResponseEntityFactory.internalServerErrorResponse("Unexpected error has occurred.", ex); 
    } 
} 

Sto cercando di scrivere un test di integrazione utilizzando il framework Spring MVC test. Questo è quello che ho finora:

@RunWith(MockitoJUnitRunner.class) 
public class ExceptionControllerTest { 
    private MockMvc mockMvc; 

    @Mock 
    private StatusController statusController; 

    @Before 
    public void setup() { 
     this.mockMvc = MockMvcBuilders.standaloneSetup(new ExceptionController(), statusController).build(); 
    } 

    @Test 
    public void checkUnexpectedExceptionsAreCaughtAndStatusCode500IsReturnedInResponse() throws Exception { 

     when(statusController.checkHealth()).thenThrow(new RuntimeException("Unexpected Exception")); 

     mockMvc.perform(get("/api/status")) 
       .andDo(print()) 
       .andExpect(status().isInternalServerError()) 
       .andExpect(jsonPath("$.error").value("Unexpected Exception")); 
    } 
} 

io registrare l'ExceptionController e un finto StatusController nell'infrastruttura Spring MVC. Nel metodo di test ho impostato un'aspettativa per generare un'eccezione da StatusController.

È stata generata un'eccezione, ma EccezioneController non ha a che fare con esso.

Desidero poter verificare che ExceptionController ottenga eccezioni e restituisca una risposta appropriata.

Qualche idea sul perché questo non funziona e come dovrei fare questo tipo di test?

Grazie.

+0

Immagino che nel test i gestori di eccezioni non vengano assegnati, non so perché esattamente ma questo è il motivo per cui accade, guarda questa risposta http: // stackoverflow. it/questions/11649036/exceptionhandler-not-working-with-spring-mvc-3-1-unit-test – engma

+0

Qualche notizia a riguardo? Sono nella stessa situazione. – Cemo

+0

Non ho trovato una soluzione. Ho deciso che mi sarei fidato di @ExceptionHandler e visto che il metodo è semplice ho deciso che potrei vivere senza testare quell'annotazione. È ancora possibile testare il metodo con un test unitario regolare. – C0deAttack

risposta

0

Poiché si utilizza il test di installazione autonomo è necessario fornire manualmente il gestore di eccezioni.

mockMvc= MockMvcBuilders.standaloneSetup(adminCategoryController).setSingleView(view) 
     .setHandlerExceptionResolvers(getSimpleMappingExceptionResolver()).build(); 

ho avuto lo stesso problema qualche giorno fa, è possibile vedere il mio problema e la soluzione risposto da solo qui Spring MVC Controller Exception Test

sperando che la mia risposta è stata fuori

-1

Provalo;

@RunWith(value = SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration(classes = { MVCConfig.class, CoreConfig.class, 
     PopulaterConfiguration.class }) 
public class ExceptionControllerTest { 

    private MockMvc mockMvc; 

    @Mock 
    private StatusController statusController; 

    @Autowired 
    private WebApplicationContext wac; 

    @Before 
    public void setup() { 
     this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); 
    } 

    @Test 
    public void checkUnexpectedExceptionsAreCaughtAndStatusCode500IsReturnedInResponse() throws Exception { 

     when(statusController.checkHealth()).thenThrow(new RuntimeException("Unexpected Exception")); 

     mockMvc.perform(get("/api/status")) 
       .andDo(print()) 
       .andExpect(status().isInternalServerError()) 
       .andExpect(jsonPath("$.error").value("Unexpected Exception")); 
    } 
} 
3

Questo codice aggiungerà la possibilità di utilizzare i consigli delle eccezioni controllate.

@Before 
public void setup() { 
    this.mockMvc = standaloneSetup(commandsController) 
     .setHandlerExceptionResolvers(withExceptionControllerAdvice()) 
     .setMessageConverters(new MappingJackson2HttpMessageConverter()).build(); 
} 

private ExceptionHandlerExceptionResolver withExceptionControllerAdvice() { 
    final ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() { 
     @Override 
     protected ServletInvocableHandlerMethod getExceptionHandlerMethod(final HandlerMethod handlerMethod, 
      final Exception exception) { 
      Method method = new ExceptionHandlerMethodResolver(ExceptionController.class).resolveMethod(exception); 
      if (method != null) { 
       return new ServletInvocableHandlerMethod(new ExceptionController(), method); 
      } 
      return super.getExceptionHandlerMethod(handlerMethod, exception); 
     } 
    }; 
    exceptionResolver.afterPropertiesSet(); 
    return exceptionResolver; 
} 
30

Ho appena avuto lo stesso problema e le seguenti opere per me:

@Before 
public void setup() { 
    this.mockMvc = MockMvcBuilders.standaloneSetup(statusController) 
     .setControllerAdvice(new ExceptionController()) 
     .build(); 
} 
+3

Dalla primavera 4.x.x ..... –

0

Questo è meglio:

((HandlerExceptionResolverComposite) wac.getBean("handlerExceptionResolver")).getExceptionResolvers().get(0) 

E non dimenticate di eseguire la scansione per i fagioli @ControllerAdvice nella vostra @Configurazione classe:

@ComponentScan(basePackages = {"com.company.exception"}) 

... testato su Spring 4.0.2.RELEASE