使用MockMvc和Spring REST Docs时重用Spring Boot ErrorAttributes

时间:2017-05-07 20:16:31

标签: spring-boot mockito mockmvc spring-restdocs

我正在为控制器编写测试,该控制器会抛出一个自定义异常(在我的情况下为AuthenticationException),该控件使用@ResponseStatus(value = HttpStatus.BAD_REQUEST)进行注释

使用ie curl调用抛出异常的端点工作正常,我得到了预期的结果,如下所示:

{
  "timestamp": 1494185397677,
  "status": 400,
  "error": "Bad Request",
  "exception": "com.example.exception.AuthenticationException",
  "message": "These are not the credentials you are looking for",
  "path": "/status/throw/2"
}

当我使用willThrow()为Mockito编写测试时,我不会获得Spring Boot生成的任何输出,而只是在我的异常类中注释的响应代码。

这是我的测试:

@Test
public void throwsShouldShowResponseBody() throws Exception {
    given(this.service.getAccStatus())
            .willThrow(AuthenticationException.class);

    this.mvc.perform(get("/status/throw/2"))
            .andExpect(status().isBadRequest())
            .andDo(document("bad-credentials"));
}

看着类似的问题,似乎这可能是由于MockMvc没有遵循重定向,我认为Spring Boot正在使用推送到/错误但是我的问题是,无论如何我可以做这个工作所以我不必写@ControllerAdvice类与Spring Boot已经提供的类似ErrorAttributes的类。我不希望更改Spring Boot在出错时生成的输出。

谢谢 -

2 个答案:

答案 0 :(得分:2)

正如您所指出的,在使用MockMvc时记录Spring Boot的错误响应有点棘手。这是因为Spring Boot会将请求转发到映射到/error的错误控制器,而MockMvc默认不会处理转发。

记录错误响应的一种方法是直接使用适当配置的请求调用/error。有一个example of this in one of Spring REST Docs' samples

@Test
public void errorExample() throws Exception {
    this.mockMvc
        .perform(get("/error")
            .requestAttr(RequestDispatcher.ERROR_STATUS_CODE, 400)
            .requestAttr(RequestDispatcher.ERROR_REQUEST_URI, "/notes")
            .requestAttr(RequestDispatcher.ERROR_MESSAGE, "The tag 'http://localhost:8080/tags/123' does not exist"))
        .andExpect(status().isBadRequest())
        .andExpect(jsonPath("error", is("Bad Request")))
        .andExpect(jsonPath("timestamp", is(notNullValue())))
        .andExpect(jsonPath("status", is(400)))
        .andExpect(jsonPath("path", is(notNullValue())))
        .andDo(this.documentationHandler.document(
            responseFields(
                fieldWithPath("error").description("The HTTP error that occurred, e.g. `Bad Request`"),
                fieldWithPath("message").description("A description of the cause of the error"),
                fieldWithPath("path").description("The path to which the request was made"),
                fieldWithPath("status").description("The HTTP status code, e.g. `400`"),
                fieldWithPath("timestamp").description("The time, in milliseconds, at which the error occurred"))));
}

然后used in the resulting documentation描述在整个API中使用的错误响应格式。

答案 1 :(得分:0)

#readMailFunctionCellReply.selected{
    background-color: pink;
}