Spring MVC @ExceptionHandler 방법에 대한 Spring MVC 시험
예상치 못한 예외를 포착할 수 있는 다음과 같은 간단한 컨트롤러가 있습니다.
@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 인프라스트럭처에 Exception Controller와 모의 Status Controller를 등록합니다.테스트 방법에서는 StatusController에서 예외를 발생시킬 것으로 예상합니다.
예외가 처리되고 있지만 예외 컨트롤러에서 처리하지 않습니다.
Exception Controller가 예외를 받고 적절한 응답을 반환하는지 테스트할 수 있기를 원합니다.
이것이 왜 작동하지 않는지 그리고 어떻게 이런 테스트를 해야 하는지에 대한 생각이 있습니까?
감사해요.
저는 방금 같은 문제가 있었고 다음 사항이 저에게 적용됩니다.
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(statusController)
.setControllerAdvice(new ExceptionController())
.build();
}
이 코드는 당신의 예외 통제된 조언을 사용할 수 있는 기능을 추가할 것입니다.
@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;
}
독립 실행형 설정 테스트를 사용하므로 수동으로 예외 처리기를 제공해야 합니다.
mockMvc= MockMvcBuilders.standaloneSetup(adminCategoryController).setSingleView(view)
.setHandlerExceptionResolvers(getSimpleMappingExceptionResolver()).build();
며칠 전에도 같은 문제가 있었는데, 여기에서 제 문제와 해결책을 직접 확인하실 수 있습니다. Spring MVC Controller Exception Test
내 대답이 당신에게 도움이 되길 바랍니다.
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);
}
}
... Record Not Found Exception Handler(기록을 찾을 수 없음 예외 처리기)
@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 "서블릿 에뮬레이터"를 구성합니다. 콘텍스트에 핸들러 빈을 등록하고 모의 MVC 에뮬레이터를 구축합니다(참고: 독립형 설정 또는 webAppContextSetup의 두 가지 가능한 구성이 있습니다. 설명서 참조).Builder는 Builder 패턴을 올바르게 구현하므로 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");
}
....
예외 확인기 가져오기
private ExceptionHandlerExceptionResolver getExceptionResolver(
StaticApplicationContext context) {
ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
resolver.getMessageConverters().add(
new MappingJackson2HttpMessageConverter());
resolver.setApplicationContext(context);
resolver.afterPropertiesSet();
return resolver;
}
테스트 실행
@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());
}
....
}
도움이 되길 바랍니다.
제이크.
해보세요;
@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"));
}
}
이것이 더 좋습니다.
((HandlerExceptionResolverComposite) wac.getBean("handlerExceptionResolver")).getExceptionResolvers().get(0)
@Configuration 클래스에서 @ControllerAdvisory bean을 검색하는 것도 잊지 마십시오.
@ComponentScan(basePackages = {"com.company.exception"})
...봄 4.0.2에 테스트를 받았습니다.풀어주다
언급URL : https://stackoverflow.com/questions/16669356/testing-spring-mvc-exceptionhandler-method-with-spring-mvc-test
'programing' 카테고리의 다른 글
| jQuery get the image src (0) | 2023.09.08 |
|---|---|
| javascript node.js next() (0) | 2023.09.08 |
| SourceTree/git에서 상호작용(시각적)으로 충돌을 해결하는 방법 (0) | 2023.09.08 |
| MySQL/SQL은 텍스트 필드의 처음 40자를 검색합니까? (0) | 2023.09.08 |
| 파이썬에서 사전을 멋지게 출력하는 방법? (0) | 2023.09.08 |