2013-05-21 24 views
28

mam następujący prosty kontroler złapać jakieś nieoczekiwane wyjątki:Metoda badawcza Wiosna MVC @ExceptionHandler z wiosennym MVC test

@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); 
    } 
} 

Próbuję napisać test integracyjny przy użyciu Spring Framework MVC Test. To, co mam tak daleko:

@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")); 
    } 
} 

I zarejestrować ExceptionController i makiety StatusController w infrastrukturze wiosny MVC. W metodzie testowej ustawiłem oczekiwanie na zgłoszenie wyjątku z kontrolera StatusController.

Wyjątek jest zgłaszany, ale narzędzie ExceptionController go nie obsługuje.

Chcę móc przetestować wyjątek ExceptionController i zwrócić odpowiednią odpowiedź.

Jakieś przemyślenia na temat tego, dlaczego to nie działa i jak powinienem wykonać ten rodzaj testu?

Dzięki.

+0

Domyślam się, że w procedurach obsługi wyjątków procedury obsługi nie zostały przypisane, nie wiem dlaczego, ale właśnie dlatego tak się dzieje, spójrz na tę odpowiedź http: // stackoverflow. com/questions/11649036/exceptionhandler-not-working-with-spring-mvc-3-1-unit-test – engma

+0

Jakieś wieści na ten temat? Jestem w tej samej sytuacji. – Cemo

+0

Nie znalazłem rozwiązania. Zdecydowałem, że zaufam, że @ExceptionHandler działa, a ponieważ sama metoda jest prosta, zdecydowałem, że mogę żyć bez testowania tej adnotacji. Nadal możesz testować metodę za pomocą zwykłego testu jednostkowego. – C0deAttack

Odpowiedz

0

Ponieważ używasz samodzielnego testu konfiguracji, musisz ręcznie podać obsługę wyjątku.

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

miałem ten sam problem kilka dni wstecz, można zobaczyć mój problem i rozwiązanie odpowiedzieć sobie tutaj Spring MVC Controller Exception Test

Licząc moja odpowiedź pomóc

-1

Wypróbuj;

@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

Ten kod doda możliwość korzystania z kontrolowanych przez Ciebie wyjątków.

@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

prostu miałem ten sam problem i następujące prace dla mnie:

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

Od wiosny 4.x.x ..... –

0

To jest lepsze:

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

I nie zapomnij o skanowanie @ControllerAdvice fasoli w swojej @Configuration class:

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

... testowany na Spring 4.0.2.RELEASE