我想测试REST控制器返回错误请求时返回的DefaultErrorAttributes
的消息。控制器抛出QueryException
,该ControllerAdvice
由@ControllerAdvice
public class ErrorHandlingControllerAdvice {
@ExceptionHandler(QueryException.class)
void onApplicationException(QueryException e, HttpServletResponse response) throws IOException {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
}
}
处理。
{
"timestamp": "2018-12-04T17:05:37.403+0000",
"status": 400,
"error": "Bad Request",
"message": "Query error message",
"path": "/search/v1/query/x"
}
响应:
WebMvcTest
ControllerAdvice
测试会在上下文中加载content().string("")
,可以正确处理异常(我检查了断点)。问题是响应的内容为空。断言@SpringJUnitConfig({QueryResource.class, ErrorHandlingControllerAdvice.class})
@WebMvcTest(QueryResource.class)
public class QueryResourceTest {
@Autowired
private MockMvc mvc;
@Test
public void testQuery() throws Exception {
String xmlQuery = ResourceHelper.loadResource("/rest/query.xml");
this.mvc.perform(post("/v1/query/test")
.contentType(MediaType.APPLICATION_XML)
.content(xmlQuery))
.andExpect(status().isBadRequest())
.andExpect(content().string(""))
.andExpect(jsonPath("$.message", is("Query error message")));
}
}
通过了,但没有通过。
{{1}}
答案 0 :(得分:1)
这:我想测试...的消息。您已成功完成。因此,我相信问题是“为什么不将响应发回以便我可以阅读?”
您正在做的是将单元测试的想法与获得结果的愿望和集成测试相结合。
发生这种情况的明显原因与运行时环境和测试环境之间的差异有关。这是因为在运行时环境中,您有一个servlet容器正在分派响应。在这里,MockMVC在不使用servlet容器的情况下运行。这意味着DefaultErrorAttributes
没有任何机制可以作为响应被分发和传播回来。
以下是支持请求,并详细说明了为什么这样做:
MockMvc doesn't use spring-boot's mvc exception handler
该GitHub问题还指向解决该问题的MockMVC SPR:
Actually support request forwarding in MockRequestDispatcher
要执行构建的测试类型的集成,您需要启动Spring Boot应用程序上下文并启动服务器。为此,只需重新编写测试类即可:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class QueryResourceTest {
// ...
}
使用WebEnvironment设置的@SpringBootTest批注在此处用于启动服务器。随着您进一步进入集成测试而不再使用MockMVC进行单元测试,可能有必要进行其他更改。