2013-05-21 36 views
28

Tôi có bộ điều khiển đơn giản sau đây để bắt bất kỳ trường hợp ngoại lệ bất ngờ:Phương pháp thử Spring MVC @ExceptionHandler với Spring MVC thử nghiệm

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

Tôi đang cố gắng để viết một bài kiểm tra tích hợp sử dụng framework Spring MVC thử nghiệm. Đây là những gì tôi có cho đến thời điểm này:

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

Tôi đăng ký ExceptionController và mô hình StatusController trong cơ sở hạ tầng Spring MVC. Trong phương pháp thử nghiệm, tôi thiết lập một kỳ vọng để ném một ngoại lệ từ StatusController.

Trường hợp ngoại lệ bị ném, nhưng ExceptionController không xử lý nó.

Tôi muốn có thể kiểm tra rằng ExceptionController có ngoại lệ và trả về phản hồi thích hợp.

Bất kỳ suy nghĩ nào về lý do tại sao điều này không hiệu quả và cách tôi nên thực hiện loại thử nghiệm này?

Cảm ơn.

+0

Tôi đoán trong việc kiểm tra xử lý ngoại lệ không được chỉ định, không biết tại sao chính xác nhưng đây là lý do tại sao nó xảy ra, nhìn vào câu trả lời http: // stackoverflow này. com/questions/11649036/exceptionhandler-không-làm việc-với-mùa xuân-mvc-3-1-đơn vị-kiểm tra – engma

+0

Bất kỳ tin tức về điều này? Tôi đang ở trong tình trạng tương tự. – Cemo

+0

Tôi không tìm thấy giải pháp. Tôi quyết định rằng tôi sẽ tin tưởng vào các tác phẩm @ExceptionHandler và vì chính phương thức đó là đơn giản, tôi quyết định tôi có thể sống mà không kiểm tra chú thích đó. Bạn vẫn có thể kiểm tra phương pháp với một bài kiểm tra đơn vị thông thường. – C0deAttack

Trả lời

0

Vì bạn đang sử dụng thử nghiệm thiết lập độc lập, bạn cần cung cấp trình xử lý ngoại lệ theo cách thủ công.

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

tôi đã cùng một vấn đề một vài ngày trở lại, bạn có thể thấy vấn đề và giải pháp của tôi đã trả lời một mình ở đây Spring MVC Controller Exception Test

Hy vọng câu trả lời của tôi giúp đỡ bạn ra

-1

Hãy thử nó;

@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

Mã này sẽ thêm khả năng sử dụng lời khuyên được kiểm soát ngoại lệ của bạn.

@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

Tôi chỉ có cùng một vấn đề và các công việc sau cho tôi:

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

Kể từ mùa xuân 4.x.x ..... –

0

này là tốt hơn:

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

Và đừng quên để quét đậu @ControllerAdvice tại của bạn @Configuration class:

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

... thử nghiệm vào mùa xuân 4.0.2.RELEASE