无法正确测试ErrorController Spring Boot

时间:2018-10-22 09:02:25

标签: spring spring-mvc spring-boot spring-test

由于本教程-https://www.baeldung.com/spring-boot-custom-error-page我想自定义错误页面,即。当有人去int getUserPosition(bool volatileCall = false) { cout << "Which slot do you want to drop the chip in (0-8)? " << endl; int startingPosition; bool isNumber = (cin >> startingPosition); while(isNumber && (startingPosition >= WIDTH || startingPosition < 0)) { cout << "Invalid slot." << endl << endl; if (volatileCall) { return -1; } cout << "Which slot do you want to drop the chip in (0-8)? " << endl; isNumber = (cin >> startingPosition); cout << startingPosition << endl; } return startingPosition; } 时,我想返回带有文本“错误的URL请求”的页面。 一切正常:

www.myweb.com/blablablalb3

但是我不知道如何测试:

@Controller
public class ApiServerErrorController implements ErrorController {

    @Override
    public String getErrorPath() {
        return "error";
    }

    @RequestMapping("/error")
    public String handleError() {
        return "forward:/error-page.html";
    }
}

print()返回:

@Test
    public void makeRandomRequest__shouldReturnErrorPage() throws Exception {
        this.mockMvc.perform(get(RANDOM_URL))
                .andDo(print());

    }

所以我不能创建这样的东西:

MockHttpServletResponse:
           Status = 404
    Error message = null
          Headers = {X-Application-Context=[application:integration:-1]}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

因为它失败,但是在手动测试中返回了错误页面。

2 个答案:

答案 0 :(得分:1)

很遗憾,不支持使用ErrorController测试自定义MockMvc

有关详细说明,请参阅Spring Boot团队(source)的官方建议。

  

为确保所有错误处理都能正常工作,有必要   让Servlet容器参与该测试,因为它负责   错误页面注册等。即使MockMvc本身或启动   MockMvc的增强功能允许转发到错误页面,   测试测试基础架构,而不是测试   您实际上对此感兴趣。

     

我们对希望确保错误处理的测试的建议   是否正常工作,是使用嵌入式容器并使用   WebTestClient,RestAssured或TestRestTemplate。

答案 1 :(得分:-2)

我的建议是使用@ControllerAdvice

通过这种方式,您可以解决此问题,并且可以继续使用MockMvc,其最大优点是不需要具有运行中的服务器。

当然要明确测试错误页面管理,您需要运行的服务器。我的建议主要针对那些实现了ErrorController但仍希望使用MockMvc进行单元测试的人。

@ControllerAdvice
public class MyControllerAdvice {

  @ExceptionHandler(FileSizeLimitExceededException.class)
  public ResponseEntity<Throwable> handleFileException(HttpServletRequest request, FileSizeLimitExceededException ex) {
    return new ResponseEntity<>(ex, HttpStatus.PAYLOAD_TOO_LARGE);
  }

  @ExceptionHandler(Throwable.class)
  public ResponseEntity<Throwable> handleUnexpected(HttpServletRequest request, Throwable throwable) {
    return new ResponseEntity<>(throwable, HttpStatus.INTERNAL_SERVER_ERROR);
  }

}