[英]How cover a ControllerAdvice dedicated to handle exception
我在測試我的 HandleException 時遇到問題,即使我已經搜索過,我只找到了集成錯誤管理的標准 controller 的解決方案,但我單獨擁有它。
問題是,在進行單元測試及其覆蓋范圍時,我不知道如何正確覆蓋它。
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(AmazonClientException.class)
protected ResponseEntity<Object> handleAmazonClientException(AmazonClientException ex) {
return buildResponseEntity(new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex));
}
@ExceptionHandler(AmazonS3Exception.class)
protected ResponseEntity<Object> handleAmazonS3Exception(AmazonS3Exception ex) {
return buildResponseEntity(new ApiError(HttpStatus.NOT_FOUND, ex));
}
private ResponseEntity<Object> buildResponseEntity(ApiError apiError) {
return new ResponseEntity<>(apiError, apiError.getStatus());
}
}
RestExceptionHandler.class
ApiError.class
@Data
public class ApiError {
private HttpStatus status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime timestamp;
private String message;
private String debugMessage;
private ApiError() {
setTimestamp(LocalDateTime.now());
}
ApiError(HttpStatus status) {
this();
setStatus(status);
}
ApiError(HttpStatus status, Throwable ex) {
this();
setStatus(status);
setMessage("Unexpected error");
setDebugMessage(ex.getLocalizedMessage());
}
ApiError(HttpStatus status, String message, Throwable ex) {
this();
setStatus(status);
setMessage(message);
setDebugMessage(ex.getLocalizedMessage());
}
}
怎么看,我只使用我的 RestExceptionHandler,而不是調用另一個業務 class。
任何建議表示贊賞。
要對@ControllerAdvice
注釋類進行單元測試,您可以使用 Spring 提供的稱為MockMvc
的東西。 這是對控制器和后續 controller 建議進行單元測試的一種非常優雅的方式。
所以,假設這是我的 controller
@RestController
@RequestMapping("api")
public class RobotController {
private RobotService robotService;
@GetMapping
public Collection<Integer> get() {
throw new DemoException();
}
}
這是我的 controller 建議; DemoException
只是一個擴展RuntimeException
的空 class 。
@RestControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(DemoException.class)
public ResponseEntity<Object> handleException(DemoException dex) {
return ResponseEntity
.status(400)
.body("Bad request");
}
}
所以,這意味着,向BASEURL/api
發送一個 GET 請求會給我帶有 400 狀態碼的Bad request
文本響應。
好的,既然我們已經完成了設置,讓我們進入實際的單元測試。 這是一個非常簡單的單元測試,但它可以滿足您的需求。
public class AdviceTest {
private final MockMvc mockMvc = MockMvcBuilders
.standaloneSetup(new RobotController())
.setControllerAdvice(new RestExceptionHandler())
.build();
@Test
void testGetFails() {
mockMvc.perform(
MockMvcRequestBuilders.get("/api")
).andExpect(
status().isBadRequest()
);
}
}
那么,讓我解釋一下MockMvc
object 的初始化。 有兩個版本。
您只需提供手動創建的 controller 對象的獨立設置。
Web 應用程序上下文,您只需在其中提供一個自動裝配的應用程序上下文。
您還可以自動裝配MockMvc
object。
在這兩個中,我真的很喜歡前者,因為它不包括整個 Spring 上下文,因此它更快。
有很多方法可以檢查 json 內容到路徑。 你可以在這里閱讀更多:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.