Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么MockMvc请求在测试成功时检索空响应库?_Java_Spring Boot_Rest_Junit5_Mockmvc - Fatal编程技术网

Java 为什么MockMvc请求在测试成功时检索空响应库?

Java 为什么MockMvc请求在测试成功时检索空响应库?,java,spring-boot,rest,junit5,mockmvc,Java,Spring Boot,Rest,Junit5,Mockmvc,我试图测试我的SpringBootREST控制器,以检查如果bean验证失败,请求是否会发送错误 我有一个@RestController: @RestController @请求映射(“/restaurants”) 公共类餐厅主控器{ 私人最终餐厅服务餐厅服务; 私有最终产品存储库产品存储库; 私人最终产品映射器ProductMapper; 公共餐厅SAP控制器(餐厅服务餐厅服务、产品存储库产品存储库、产品映射器产品映射器){ this.restaurantService=restaurantS

我试图测试我的SpringBootREST控制器,以检查如果bean验证失败,请求是否会发送错误

我有一个@RestController:

@RestController
@请求映射(“/restaurants”)
公共类餐厅主控器{
私人最终餐厅服务餐厅服务;
私有最终产品存储库产品存储库;
私人最终产品映射器ProductMapper;
公共餐厅SAP控制器(餐厅服务餐厅服务、产品存储库产品存储库、产品映射器产品映射器){
this.restaurantService=restaurantService;
this.productRepository=productRepository;
this.productMapper=productMapper;
}
@后期映射(“{id}/产品”)
public ResponseEntity addProduct(@PathVariable Long id,
@有效@RequestBody ProductDto ProductDto){
Product Product=this.restaurantService.addProduct(id,productMapper.ProductdToProduct(productDto));
返回新的ResponseEntity(productMapper.productToProductDto(product),HttpStatus.CREATED);
}
我有一个带有@ControllerAdvice注释的自定义异常处理程序:

@ControllerAdvice
公共类例外ControllerAdvice{
@ExceptionHandler({MethodArgumentNotValidException.class})
公共响应验证异常(MethodArgumentNotValidException ex,WebRequest){
....
//在这里,我格式化我的自定义错误消息
返回新的ResponseEntity(APIRROR,new-HttpHeaders(),APIRROR.getStatus());
}
如果验证失败,它将完美运行并向我发送此自定义响应:

{
    "status": "BAD_REQUEST",
    "errors": {
        "price": "doit être supérieur ou égal à 0",
        "name": "ne doit pas être nul",
        "category": "ne doit pas être nul"
    }
}
我尝试使用mockMvc来测试这个测试类的行为:

@ExtendWith(MockitoExtension.class)
类餐厅SAP控制器测试{
@嘲弄
私人餐馆服务;
@嘲弄
私有产品存储库产品存储库;
@嘲弄
私有ProductMapper ProductMapper;
@注射模拟
私家餐馆主控器;
MockMvc-MockMvc;
@之前
无效设置(){
mockMvc=MockMvcBuilders.standaloneSetup(controller.build();
}
@试验
void givenInvalidFrom_,此时产品应通过wexException()引发异常{
//产品缺少名称、类别,且价格为负值,这是验证批注所禁止的
ProductDto ProductDto=ProductDto.builder().id(1L).price(-10.5D).build();
MvcResult MvcResult=mockMvc.perform(post(“/restaurants/1/products”)
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(productDto)))
.andExpect(状态().isBadRequest())
.andReturn();
字符串结果=mvcResult.getResponse().getContentAsString();
然后(餐厅服务)。应该进行评论();
}
测试完全通过,我可以在日志中看到验证异常正确预期:

14:53:30.345 [main] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument ...
//I removed the rest of the message for readability, but each validation exception appears here properly
14:53:30.348 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Completed 400 BAD_REQUEST
但是我找不到一种方法来测试我的错误映射是否包含我期望的字段。当我尝试使用以下内容检索响应正文时:

String result=mvcResult.getResponse().getContentAsString();
字符串是空的,我找不到任何方法来测试响应体

我完全不知道,如果能帮上忙,我将不胜感激

非常感谢

MvcResult mvcResult = mockMvc.perform(post("/restaurants/1/products")
                .contentType(MediaType.APPLICATION_JSON)
                .content(asJsonString(productDto)))
                .andExpect(status().isBadRequest())
                .andExpect(content().string("Your content"))
                .andReturn();   
或者使用自定义匹配器

MvcResult mvcResult = mockMvc.perform(post("/restaurants/1/products")
                .contentType(MediaType.APPLICATION_JSON)
                .content(asJsonString(productDto)))
                .andExpect(status().isBadRequest())
                .andExpect(content().string(new CustomMatcher()))
                .andReturn();

    private static class ContentMatcher extends CustomMatcher<String>{

            public ContentMatcher() {
                super("");
            }

            @Override
            public boolean matches(Object o) {
                final String expected="Some long wide string " +
                        "wich i should check" +
                        "...."
                return o.equals(expected);
            }
        }
MvcResult MvcResult=mockMvc.perform(post(“/restaurants/1/products”)
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(productDto)))
.andExpect(状态().isBadRequest())
.andExpect(content().string(新的CustomMatcher()))
.andReturn();
私有静态类ContentMatcher扩展了CustomMatcher{
公共内容匹配器(){
超级(“”);
}
@凌驾
公共布尔匹配(对象o){
应为final String=“一些长宽字符串”+
“我该去查一下”+
"...."
回报等于(预期);
}
}

使用builder配置MockMvc实例时,请进行以下更新:

MockMvcBuilders
    .standaloneSetup(controller)
    .setControllerAdvice(new ExceptionControllerAdvice())
    .build()
您应该手动将控制器建议设置为模拟mvc上下文,否则它将被忽略。
此更新后,您将收到错误响应中的正文。如果您想验证Json正文,请使用上述答案中的Json path API。

感谢您的回答,它确实有效,但根本不实用。我无法将完整响应粘贴到其中,因为它太长,无法读取。您知道是否还有其他方法可以检索吗内容,并且能够在外部处理它?谢谢!我已经更改了答案-你可能看起来可以做得很好!非常感谢,这是个错误。现在我可以访问响应主体,并使用jsonPath使用
.andExpect(jsonPath(“errors.price”).exists())和expect(jsonPath(“errors.name”).exists())对其进行测试.andExpect(jsonPath(“errors.category”).exists();
非常感谢!祝您编码愉快!)