[SPRING] Spring MVC 테스트 @ExceptionHandler 메소드
SPRINGSpring MVC 테스트 @ExceptionHandler 메소드
예기치 않은 예외를 잡기 위해 다음과 같은 간단한 컨트롤러가 있습니다.
@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);
}
}
Spring MVC Test 프레임 워크를 사용하여 통합 테스트를 작성하려고합니다. 이것은 내가 지금까지 가지고있는 것이다 :
@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"));
}
}
Spring MVC 인프라에서 ExceptionController와 mock StatusController를 등록한다. 테스트 메서드에서 나는 StatusController로부터 예외를 던질 것을 기대했다.
예외가 발생하지만 ExceptionController가 처리하지 않습니다.
ExceptionController가 예외를 얻고 적절한 응답을 리턴하는지 테스트 할 수 있기를 원합니다.
왜 이것이 작동하지 않는지에 대한 생각과 이런 종류의 테스트를 어떻게해야합니까?
감사.
해결법
-
==============================
1.나는 지금 막 동일한 문제 및 뒤에 오는 일이 저를 위해 있었다 :
나는 지금 막 동일한 문제 및 뒤에 오는 일이 저를 위해 있었다 :
@Before public void setup() { this.mockMvc = MockMvcBuilders.standaloneSetup(statusController) .setControllerAdvice(new ExceptionController()) .build(); }
-
==============================
2.이 코드는 예외 제어 된 조언을 사용할 수있는 기능을 추가합니다.
이 코드는 예외 제어 된 조언을 사용할 수있는 기능을 추가합니다.
@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; }
-
==============================
3.독립 실행 형 설치 테스트를 사용하고 있으므로 수동으로 예외 처리기를 제공해야합니다.
독립 실행 형 설치 테스트를 사용하고 있으므로 수동으로 예외 처리기를 제공해야합니다.
mockMvc= MockMvcBuilders.standaloneSetup(adminCategoryController).setSingleView(view) .setHandlerExceptionResolvers(getSimpleMappingExceptionResolver()).build();
며칠 전 동일한 문제가 발생했습니다. 내 문제와 해결책을 직접 볼 수 있습니다. 스프링 MVC 컨트롤러 예외 테스트
내 대답이 너를 도우려는 걸 원해.
-
==============================
4.Spring MockMVC를 사용하여 단위 테스트 스위트에서 요청 필터링 또는 예외 처리 테스트를 통합 할 수있는 지점까지 servletContainer를 에뮬레이트하십시오.
Spring MockMVC를 사용하여 단위 테스트 스위트에서 요청 필터링 또는 예외 처리 테스트를 통합 할 수있는 지점까지 servletContainer를 에뮬레이트하십시오.
다음 방법을 사용하여이 설정을 구성 할 수 있습니다.
사용자 정의 RecordNotFound 예외가 발생했습니다 ...
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Record not found") // public class RecordNotFoundException extends RuntimeException { private static final long serialVersionUID = 8857378116992711720L; public RecordNotFoundException() { super(); } public RecordNotFoundException(String message) { super(message); } }
... 및 RecordNotFound 예외 핸들러
@Slf4j @ControllerAdvice public class BusinessExceptionHandler { @ExceptionHandler(value = RecordNotFoundException.class) public ResponseEntity<String> handleRecordNotFoundException( RecordNotFoundException e, WebRequest request) { //Logs LogError logging = new LogError("RecordNotFoundException", HttpStatus.NOT_FOUND, request.getDescription(true)); log.info(logging.toJson()); //Http error message HttpErrorResponse response = new HttpErrorResponse(logging.getStatus(), e.getMessage()); return new ResponseEntity<>(response.toJson(), HeaderFactory.getErrorHeaders(), response.getStatus()); } ... }
맞춤형 테스트 컨텍스트 구성 : @ContextConfiguration을 설정하여 테스트에 필요한 클래스를 지정하십시오. Mockito MockMvc를 서블릿 컨테이너 에뮬레이터로 설정하고 테스트 픽스처와 의존성을 설정하십시오.
@RunWith(SpringRunner.class) @ContextConfiguration(classes = { WebConfig.class, HeaderFactory.class, }) @Slf4j public class OrganisationCtrlTest { private MockMvc mvc; private Organisation coorg; @MockBean private OrganisationSvc service; @InjectMocks private OrganisationCtrl controller = new OrganisationCtrl(); //Constructor public OrganisationCtrlTest() { } ....
모의 MVC "서블릿 에뮬레이터"를 설정합니다 : 컨텍스트에서 핸들러 빈을 등록하고 mockMvc 에뮬레이터를 빌드하십시오 (참고 : 두 가지 가능한 구성이 있습니다 : standaloneSetup 또는 webAppContextSetup, 문서 참조). 빌더는 빌더 패턴을 올바르게 구현하므로 build ()를 호출하기 전에 예외 확인 자 및 핸들러에 대한 구성 명령을 연결할 수 있습니다.
@Before public void setUp() { final StaticApplicationContext appContext = new StaticApplicationContext(); appContext.registerBeanDefinition("BusinessExceptionHandler", new RootBeanDefinition(BusinessExceptionHandler.class, null, null)); //InternalExceptionHandler extends ResponseEntityExceptionHandler to //handle Spring internally throwned exception appContext.registerBeanDefinition("InternalExceptionHandler", new RootBeanDefinition(InternalExceptionHandler.class, null, null)); MockitoAnnotations.initMocks(this); mvc = MockMvcBuilders.standaloneSetup(controller) .setHandlerExceptionResolvers(getExceptionResolver(appContext)) .build(); coorg = OrganisationFixture.getFixture("orgID", "name", "webSiteUrl"); } ....
테스트를 실행하십시오.
@Test public void testGetSingleOrganisationRecordAnd404() throws Exception { System.out.println("testGetSingleOrganisationRecordAndSuccess"); String request = "/orgs/{id}"; log.info("Request URL: " + request); when(service.getOrganisation(anyString())). thenReturn(coorg); this.mvc.perform(get(request) .accept("application/json") .andExpect(content().contentType( .APPLICATION_JSON)) .andExpect(status().notFound()) .andDo(print()); } .... }
희망이 도움이됩니다.
제이크.
-
==============================
5.이게 낫다:
이게 낫다:
((HandlerExceptionResolverComposite) wac.getBean("handlerExceptionResolver")).getExceptionResolvers().get(0)
그리고 @Configuration 클래스에서 @ControllerAdvice 빈을 스캔하는 것을 잊지 마십시오.
@ComponentScan(basePackages = {"com.company.exception"})
... Spring 4.0.2에서 테스트되었습니다.
-
==============================
6.시도 해봐;
시도 해봐;
@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")); } }
from https://stackoverflow.com/questions/16669356/testing-spring-mvc-exceptionhandler-method-with-spring-mvc-test by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] HTML과 JSON 요청에 대해 Spring MVC에서 예외를 다르게 처리하는 방법 (0) | 2019.03.04 |
---|---|
[SPRING] Joda DateTime을 ISO 8601 형식으로 자동 포맷 (0) | 2019.03.04 |
[SPRING] Spring 4.1에서 사용중인 Jackson ObjectMapper를 얻으려면 어떻게해야합니까? (0) | 2019.03.04 |
[SPRING] Spring ApplicationListener가 이벤트를 수신하지 않습니다. (0) | 2019.03.04 |
[SPRING] Spring에서 GET 및 POST 요청 메소드 결합 (0) | 2019.03.04 |