代码之家  ›  专栏  ›  技术社区  ›  Sydney

为什么在SpringWebmVectest中没有响应主体

  •  1
  • Sydney  · 技术社区  · 6 年前

    我想测试一下 DefaultErrorAttributes 当REST控制器返回错误请求时返回。控制器抛出一个 QueryException 由A处理 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 测试负载 管制员建议 在上下文中,异常被正确地处理(我用一个断点检查)。问题是响应的内容是空的。断言 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 回复  |  直到 6 年前
        1
  •  1
  •   Randy Casburn    6 年前

    这是: 我想测试一下… 您已成功完成。所以我认为问题是,“为什么不把回复发回去,这样我就可以读出来了?”

    您要做的是将单元测试的思想与获得结果的愿望(就好像它是)和集成测试混合在一起。

    发生这种情况的明显原因与运行时环境和测试环境之间的差异有关。这是因为在运行时环境中,有一个servlet容器正在调度响应。这里,mockmvc运行时不使用servlet容器。这意味着 DefaultErrorAttributes 作为响应进行调度和传播。

    下面是一个支持请求,并详细解释了为什么要这样做:

    MockMvc doesn't use spring-boot's mvc exception handler

    Github问题还指向一个mockmvc spr来解决这个问题:

    Actually support request forwarding in MockRequestDispatcher

    要执行所构建的测试类型的集成,您需要启动Spring引导应用程序上下文并启动服务器。要做到这一点,只需重新包装测试类,这样:

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    public class QueryResourceTest {
       // ...
    }
    

    使用webenvironment设置的@springbootstest注释用于启动服务器。其他的更改可能是必要的,因为您将更多地转移到集成测试中,而不是使用mockmvc进行单元测试。