【问题标题】:Testing a Spring Boot application with custom ErrorAttributes?使用自定义 ErrorAttributes 测试 Spring Boot 应用程序?
【发布时间】:2015-05-21 04:07:23
【问题描述】:

我正在尝试测试应使用自定义错误属性的 Spring Boot RestController。

    @Bean
public ErrorAttributes errorAttributes() {
    return new DefaultErrorAttributes() {

        @Override
        public Map<String, Object> getErrorAttributes(
                RequestAttributes requestAttributes,
                boolean includeStackTrace) {
            Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
            Throwable error = getError(requestAttributes);
            return errorAttributes;
        }

    };
}

但是当我尝试使用简单的测试来测试自定义错误属性时,这些属性没有被考虑在内。下面的测试实际上触发了一个请求,并且 i 除了使用了自定义属性。但无论我似乎做什么,代码似乎都没有被考虑在内。

class TestSpec extends Specification {

    MockMvc mockMvc

    def setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build()
    }

    def "Test simple action"() {
        when:
        def response = mockMvc.perform(post("/hello")
                .contentType(MediaType.APPLICATION_JSON)
                .content('{"sayHelloTo": ""}')
        )

        then:
        response.andExpect(status().isOk())
    }
}

关于如何测试自定义属性是否有任何线索?

【问题讨论】:

    标签: spring rest spring-boot


    【解决方案1】:

    Spring Boot 的错误基础架构通过将请求转发到错误控制器来工作。正是这个错误控制器使用了ErrorAttributes 实例。 MockMvc 仅对测试请求的转发提供了相当基本的支持(您可以检查请求是否会被转发,但不能检查该转发的实际结果)。这意味着调用您的 HellowWorldController 的 MockMvc 测试,无论是使用独立设置还是基于 Web 应用程序上下文的设置,都不会驱动正确的代码路径。

    几个选项:

    • 直接对您的自定义 ErrorAttributes 类进行单元测试
    • 编写一个基于 MockMvc 的测试,调用 Spring Boot 的 BasicErrorController,并使用您的自定义 ErrorAttributes 实例进行配置
    • 编写一个集成测试,使用 RestTemplate 对您的服务进行实际的 HTTP 调用

    【讨论】:

    • 你有一个例子如何实现第二种方法吗?我无法理解这一点。
    • 嗨,安迪,感谢您的回复。我什至无法正确检查请求是否已转发。调试的时候看到MockHttpServletResponseforwardedUrl是null但是不应该转发到/error吗?在MockMvc 中应用此转发是否有任何必要的配置?
    【解决方案2】:

    test class from Spring 为您提供了一个开始自己测试的好地方!

    创建自定义错误属性类的实例并使用 MockHttpServletRequest 和 WebRequest:

    private final DefaultErrorAttributes errorAttributes = new YourCustomErrorAttributes();
    private final MockHttpServletRequest request = new MockHttpServletRequest();
    private final WebRequest webRequest = new ServletWebRequest(this.request);
    

    对于您的测试方法:

    //Set the appropriate error state in your mocked request object:
    RuntimeException ex = new RuntimeException("Test");
    this.request.setAttribute("javax.servlet.error.exception", ex);
    
    //Pass the mocked request into the the methods that are normally called by the framework 
    Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(this.webRequest, ErrorAttributeOptions.of(Include.STACK_TRACE));   
    
    // add your own asserts
    assertThat(attributes.get("trace").toString()).startsWith("java.lang");
    

    【讨论】:

      猜你喜欢
      • 2016-07-01
      • 1970-01-01
      • 2017-04-01
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 2018-07-22
      相关资源
      最近更新 更多