在spring boot项目中,我想用Junit测试我的ErrorController。 代码如下面的代码段所示。
@RestController
public class ApiErrorController implements ErrorController {
private static final Logger LOGGER = LoggerFactory.getLogger(ApiErrorController.class);
@Value("${server.error.path}")
private String errorPath;
@Override
public String getErrorPath() {
return this.errorPath;
}
@RequestMapping("/error")
public ResponseEntity<ErrorResult> error(HttpServletRequest request, HttpServletResponse response) {
String requestURI = (String) request.getAttribute("javax.servlet.forward.request_uri");
LOGGER.info("error handling start url = {}", requestURI);
String servletMessage = (String) request.getAttribute("javax.servlet.error.message");
Integer servletStatus = (Integer) request.getAttribute("javax.servlet.error.status_code");
String[] messages = new String[0];
if (!StringUtils.isNullOrEmpty(servletMessage)) {
messages = new String[] { servletMessage };
}
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
try {
if (servletStatus != null && servletStatus instanceof Integer) {
status = HttpStatus.valueOf(servletStatus);
}
} catch (Exception ex) { // test this exception
LOGGER.warn("http status not converted.{}", request.getAttribute("javax.servlet.error.status_code"), ex);
}
ErrorResult body = new ErrorResult();
body.setMessages(messages);
ResponseEntity<ErrorResult> responseResult = new ResponseEntity<>(body, status);
return responseResult;
}
}
当我的Controller中发生业务异常时(例如AbcController),程序进入ExceptionControllerAdvice类。 如果ExceptionControllerAdvice中发生异常,则程序进入上述ApiErrorController类。
有人能告诉我如何测试HttpStatus.valueOf(servletStatus)
失败的情况吗?
另外,我希望request.getAttribute("javax.servlet.error.message")
返回一个非空字符串。
如何实现我想测试的内容?
顺便说一句,我不想只测试error
方法的逻辑。我想用我提到的AbcController
进行测试。我想要的是当AbcController
中发生错误时,error
中的ApiErrorController
方法可以成功处理它。
APPEND :
例如,ExceptionControllerAdvice
将处理业务异常。
@ControllerAdvice(annotations = RestController.class)
public class ExceptionControllerAdvice {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionControllerAdvice.class);
@ExceptionHandler({ BusinessCloudException.class })
public ResponseEntity<ErrorResult> handleBlCloudException(HttpServletRequest request, HttpServletResponse response,
BlCloudException ex) {
HttpStatus status = ErrorUtils.toHttpStatus(ex.getType());
ErrorResult body = new ErrorResult();
body.setMessages(ex.getMessageArray());
ResponseEntity<ErrorResult> responseResult = new ResponseEntity<>(body, status);
return responseResult;
}
}
如果handleBlCloudException
方法中发生错误,则程序会进入ApiErrorController
以处理此错误。
该程序如何生成特定的servletStatus
和javax.servlet.error.message
?如何嘲笑这样做?
答案 0 :(得分:0)
首先,该错误方法有很多事情要做。您可以考虑将一些逻辑移动到专门的类/公共方法。
除此之外,我建议使用Mockito。
Fist of all创建一个封装HttpStatus检索的方法:
HttpStatus getHttpStatusByServletStatus(Integer servletStatus){
return HttpStatus.valueOf(servletStatus);
}
并将您的代码更改为:
if (servletStatus != null && servletStatus instanceof Integer) {
status = getHttpStatusByServletStatus(servletStatus);
}
然后是测试类:
public ApiErrorControllerTest {
@Spy
private ApiErrorController apiErrorController;
@Mock
HttpServletRequest requestMock;
@Mock
HttpServletResponse responseMock;
@Befire
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void test(){
// Arrange
HttpStatus expectedStatus = // expected status
String expectedErrorMessage = // ..
doReturn(expectedStatus).when(apiErrorController)
.getHttpStatusByServletStatus(Mockito.anyString());
when(requestMock.getAttribute("javax.servlet.error.message"))
.thenReturn(expectedErrorMessage);
// other setup..
// Act
apiErrorController.error(requestMock, responseMock);
// Assertions
}