spring-boot - 使用 MockMvc 和 Spring REST 文档时重用 Spring Boot ErrorAttributes

标签 spring-boot mockito mockmvc spring-restdocs

我正在为抛出自定义异常(在我的情况下是AuthenticationException)的 Controller 编写测试,该异常用@ResponseStatus(value = HttpStatus.BAD_REQUEST)进行注释

使用即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"
}

当我使用 Mockito 编写一个使用 willThrow() 的测试时,我没有得到 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 正在使用它来推送到/error 但我的问题是是否有无论如何我可以完成这项工作,所以我不必编写@ControllerAdvice 类,与 Spring Boot 已经提供的 ErrorAttributes 类似。我不想更改 Spring Boot 在出现错误时生成的输出。

谢谢-

最佳答案

正如您所注意到的,使用 MockMvc 时记录 Spring Boot 的错误响应有点棘手。这是因为 Spring Boot 将请求转发到映射到 /error 的错误 Controller ,而 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 中使用的错误响应格式。

关于spring-boot - 使用 MockMvc 和 Spring REST 文档时重用 Spring Boot ErrorAttributes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43836231/

相关文章:

java - 如何使用具有特定属性的参数对方法进行 stub

java - 想要创建动态 mongo 查询来接受 DTO 字段

java - Intellij 运行配置 Spring Boot 与 Maven 问题

java - java中没有@Id注释的序列生成器与Postgres中的hibernate在一定范围内

java - mockito + easymock - NoClassDefFoundError :net/sf/cglib/proxy/Enhancer

java - MockMvc - 预期状态 :<200> but was:<302>

css - 在 spring-boot 应用程序中获取用于下载字体文件 (ttf) 的弹出窗口

java - Mockito 中的 Spring @Value 字段注入(inject)

java - 如何使用 MockMVC 对 Spring-Boot REST 端点进行单元测试,其中路径映射是环境变量?

spring - 无法使用 Spring MockMvc 将正文附加到我的 POST 请求