使用自定义 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 调用
【讨论】:
你有一个例子如何实现第二种方法吗?我无法理解这一点。 嗨,安迪,感谢您的回复。我什至无法正确检查请求是否已转发。调试的时候看到MockHttpServletResponse
的forwardedUrl
是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