使用自定义 ErrorAttributes 测试 Spring Boot 应用程序?

Posted

技术标签:

【中文标题】使用自定义 ErrorAttributes 测试 Spring Boot 应用程序?【英文标题】:Testing a Spring Boot application with custom ErrorAttributes? 【发布时间】: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())
    

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

【问题讨论】:

【参考方案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");

【讨论】:

以上是关于使用自定义 ErrorAttributes 测试 Spring Boot 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

springboot新版本(2.0.0+)自定义ErrorController中使用ErrorAttributes

接口测试---mock变量自定义变量的使用

使用 SetTimeout 测试自定义钩子,使用 Jest 测试 useEffect

在 Laravel 7 测试中使用自定义测试模型

如何使用属性单元测试自定义视图

Java 注解自定义注解 ( 使用注解实现简单测试框架 )