如何通过Groovy单元测试实现Bean Validation接口参数校验
解决Controller参数校验单元测试不触发ConstraintViolationException的问题
首先明确核心原因:直接调用Controller方法时,Spring MVC的参数校验拦截器不会自动生效,只有通过DispatcherServlet处理请求(比如用MockMvc模拟HTTP请求),或者手动触发校验,才能触发@NotNull、@Size等注解的校验逻辑。
下面分两种测试场景给出解决方案:
一、推荐:用MockMvc模拟HTTP请求(贴近真实场景)
这种方式会完整触发Spring MVC的请求处理流程,包括参数校验,无需手动处理。
示例代码(Groovy)
假设你的Controller和Swagger生成的请求类如下:
@RestController class UserController { @PostMapping("/users") ResponseEntity createUser(@Valid @RequestBody UserRequest request) { ResponseEntity.ok().build() } } // Swagger生成的请求DTO class UserRequest { @NotNull(message = "名称不能为空") @Size(min = 2, max = 20, message = "名称长度需在2-20之间") String name }
对应的单元测试:
@WebMvcTest(UserController) class UserControllerSpec extends Specification { @Autowired MockMvc mockMvc def "创建用户时传入null名称应触发参数校验失败"() { given: def invalidRequest = [name: null] def requestJson = new ObjectMapper().writeValueAsString(invalidRequest) when: def result = mockMvc.perform(post("/users") .contentType(MediaType.APPLICATION_JSON) .content(requestJson)) then: // 断言返回400错误 result.andExpect(status().isBadRequest()) // 可选:断言异常类型 def resolvedException = result.andReturn().resolvedException resolvedException instanceof ConstraintViolationException } }
二、直接调用Controller方法(手动触发校验)
如果必须直接调用Controller方法,需要手动使用Spring提供的Validator执行校验,无需自己创建ValidatorFactory(Spring已自动配置)。
示例代码(Groovy)
@SpringBootTest class UserControllerSpec extends Specification { @Autowired UserController userController @Autowired Validator validator def "传入null名称的请求应触发ConstraintViolationException"() { given: def invalidRequest = new UserRequest(name: null) when: // 手动执行校验 Set<ConstraintViolation<UserRequest>> violations = validator.validate(invalidRequest) then: // 断言存在校验违规 !violations.isEmpty() // 断言是name字段的违规 violations.any { it.propertyPath.toString() == "name" } // 若要模拟Controller抛出异常,可手动抛出 when: if (!violations.isEmpty()) { throw new ConstraintViolationException(violations) } userController.createUser(invalidRequest) then: thrown(ConstraintViolationException) } }
关键注意事项
- 必须添加@Valid/@Validated注解:在Controller方法的参数前加上
@Valid或@Validated,否则Spring MVC不会触发校验逻辑。 - 确认Swagger生成的DTO注解正确:检查Swagger生成的请求类上是否确实存在
@NotNull、@Size等校验注解,避免生成配置遗漏。 - 无需手动创建ValidatorFactory:Spring环境下直接
@Autowired Validator即可,底层已由Spring管理ValidatorFactory实例。
内容的提问来源于stack exchange,提问作者jcrshankar
相关产品推荐
相关产品推荐

