【问题标题】:Testing Bad Request while posting an incomplete entity with Spring Boot在使用 Spring Boot 发布不完整实体时测试错误请求
【发布时间】:2019-03-05 21:39:19
【问题描述】:

我正在尝试使用不完整数据测试创建实体,如下所示:

@Test
public void postVisitor_withIncompleteData_shouldFailWithBadRequest() throws Exception {
    Visitor emptyVisitor = new Visitor();

    mockMvc.perform(post("/visits")
            .contentType(APPLICATION_JSON)
            .content(objectMapper.writeValueAsString(visitor))
            ).andExpect(status().isBadRequest());
}

但我的测试失败并出现此错误:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [com.reweb.Visitor] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='cannot be empty', propertyPath=email, rootBeanClass=class com.reweb.Visitor, messageTemplate='{javax.validation.constraints.NotEmpty.message}'}
]

如何测试这是一个错误的请求?

添加@Test(expected = ConstraintViolationException.class) 也不起作用。

【问题讨论】:

  • 您可能没有在控制器中绑定验证器。你的控制器中有这个吗 @InitBinder private void initBinder(WebDataBinder binder) { binder.setValidator(constraintValidator); }
  • 我认为,您需要显示Visitor 的代码以及如何使用@Valid@Validatedorg.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler 不会自动处理 - ConstraintViolationException

标签: spring-boot junit spring-data-rest spring-rest mockmvc


【解决方案1】:

如果您已经在控制器中配置了@Valid 和@ResponseBody,那么您需要创建ExceptionHandlerInterceptor,如下所示:

    @RestControllerAdvice
    @Slf4j
    public class ApplicationExceptionInterceptor extends ExceptionHandlerExceptionResolver {

      @ExceptionHandler(Throwable.class)
      public
        ResponseEntity<Response<?>>
        handleControllerException(final HttpServletRequest request, final Throwable ex) {

        if (ex instanceof MethodArgumentNotValidException) {
          log.error(ex.getMessage());
          final MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
          final List<ObjectError> errors = exception.getBindingResult().getAllErrors();
          final List<FaultDetail> faultDetailsList = new ArrayList<>();
          final List<String> error = new ArrayList<>();
          errors.forEach(action -> error.add(action.getDefaultMessage()));
          faultDetailsList.add(new FaultDetail(error));

        }
return ResponseEntity.body(faultList).status(HttpStatus.BAD_REQUEST).build();
}

您还需要提供这个 ExceptionHandler 给 MockMvc ,如下所示,我为 RestAssuredMockMvc 提供了 MockMvc 的类似配置:

@BeforeMethod
public void initializeMockMvcWithControllerAdvice(Object controller, Object controllerAdvice, ContentType contentType) {
    RestAssuredMockMvc.reset();
    RestAssuredMockMvc.mockMvc(MockMvcBuilders.standaloneSetup(new Object[]{controller}).setControllerAdvice(new Object[]{controllerAdvice}).build());
    RestAssuredMockMvc.requestSpecification = (new MockMvcRequestSpecBuilder()).setContentType(contentType).build();
  }

【讨论】:

    猜你喜欢
    • 2020-12-09
    • 2022-01-10
    • 2016-11-20
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多