簡體   English   中英

如何覆蓋專用於處理異常的 ControllerAdvice

[英]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 的初始化。 有兩個版本。

  1. 您只需提供手動創建的 controller 對象的獨立設置

  2. Web 應用程序上下文,您只需在其中提供一個自動裝配的應用程序上下文。

您還可以自動裝配MockMvc object。

在這兩個中,我真的很喜歡前者,因為它不包括整個 Spring 上下文,因此它更快。

有很多方法可以檢查 json 內容到路徑。 你可以在這里閱讀更多:

Spring 指南

貝爾東

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM