@Test
public void updateDeviceTelemetryInterval() throws Exception {
int deviceId = 1;
String serviceName = "AAAService";
//given service info
ServiceDto serviceDto = new ServiceDto();
serviceDto.setServiceId(1);
AzureIotHubEntity azureIotHubEntity = new AzureIotHubEntity();
azureIotHubEntity.setAzureIotHubConnectionString("");
serviceDto.setAzureIotHub(azureIotHubEntity);
//given device info
DeviceDto deviceDto = new DeviceDto();
deviceDto.setDeviceId(1);
//given interval info
Gson gson = new Gson();
DeviceDto device = new DeviceDto();
device.setTelemetryInterval(1);
String str = gson.toJson(device);
given(serviceService.findServiceByName(serviceName)).willReturn(serviceDto);
given(deviceService.findDeviceById(deviceId)).willReturn(deviceDto);
//when then
MockHttpServletRequestBuilder createUserRequest = post("/ServiceName/setTelemetryInterval/1")
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.content(str);
this.mvc.perform(createUserRequest)
.andExpect(status().is2xxSuccessful());
}
이와 같은 테스트코드는 정상적 상황을 테스트하는 상황입니다.
만약 해당하는 서비스가 없는 상황에서는 다음과 같은 Exception이 발생하도록 내부적으로 정의했습니다.
@ResponseStatus(value= HttpStatus.NOT_FOUND, reason="No such Service")
public class ServiceNotFoundException extends Exception {
public ServiceNotFoundException(String message){
super(message);
}
public ServiceNotFoundException(String message, Throwable cause) {
super(message,cause);
}
}
이와 같은 Exception이 의도한 것처럼 발생하는지 우리는 일반적으로 TestCode에서 아래와 같은 annotation을 통해서 처리합니다.
@Test(expected = ServiceNotFoundException.class)
그런데 여기서 주의해야 할점이 있습니다!!!
우리가 일반적으로 Spring mvc를 사용할때 위와 같은 형태로 Exception을 정의할 경우, 내부적으로 Exception을 catch하여 밖으로 나가지 않도록 하고 HTTP STATUS코드를 변경하게 됩니다.
따라서 위와 같이 @Test(expected) 를 추가하더라도 Exception은 잡히지 않습니다.
어떻게 하면 내가 의도한 Exception을 잡아낼 수 있을지 Spring 내부소스를 살펴보았습니다.
final class TestDispatcherServlet extends DispatcherServlet {
@Override
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
@Nullable Object handler, Exception ex) throws Exception {
ModelAndView mav = super.processHandlerException(request, response, handler, ex);
// We got this far, exception was processed..
DefaultMvcResult mvcResult = getMvcResult(request);
mvcResult.setResolvedException(ex);
mvcResult.setModelAndView(mav);
return mav;
}
위와 같이 result에 resolvedException에 발생한 Exception정보를 저장하고 있습니다.
그렇다면 아래와 같이 테스트 코드를 작성하면 될것이라고 추측됩니다.
@Test
public void updateDeviceTelemetryIntervalNonExistService() throws Exception {
//given
ServiceDto serviceDto = new ServiceDto();
Gson gson = new Gson();
DeviceDto device = new DeviceDto();
device.setTelemetryInterval(1);
String str = gson.toJson(device);
given(serviceService.findServiceByName("TestService")).willReturn(serviceDto);
//when then
MockHttpServletRequestBuilder createUserRequest = post("/AAAService/setTelemetryInterval/1")
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.content(str);
this.mvc.perform(createUserRequest)
.andExpect((result)->assertTrue(result.getResolvedException().getClass().isAssignableFrom(ServiceNotFoundException.class)))
.andExpect(status().is4xxClientError());
}
테스트 결과 404 NotFound 와 exception의 유형을 모두 확인할 수 있습니다.
'Java' 카테고리의 다른 글
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException (0) | 2021.05.07 |
---|---|
Spring Security + MySQL 사용시 로그인 대소문자 구분 주의사항 (0) | 2019.09.11 |
Spring JPA + Azure Cosmos DB 연결 (라이브러리 변경관련 트러블슈팅) (0) | 2019.03.14 |
Oracle 11g JDBC Driver에서 Hang이 발생하는 경우 (0) | 2017.02.20 |
FTP connection reset에 관련된 오류해결 (0) | 2016.04.05 |