我正在尝试在Spring Boot 1.4中执行单元测试来测试我的验证在无效的查询字符串参数上返回400.
控制器
@RestController
@Validated
public class ExampleController {
...
@RequestMapping(value = "/example", method = GET)
public Response getExample(
@RequestParam(value = "userId", required = true) @Valid @Pattern(regexp = MY_REGEX) String segmentsRequest {
// Stuff here
}
}
异常处理程序
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
// 400 - Bad Request
@ExceptionHandler(value = {ConstraintViolationException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void constrainViolationHandle(HttpServletRequest request, ConstraintViolationException exception) {
logger.error("Error Bad Request (400)");
}
}
上下文
@Bean
public Validator validator() {
final ValidatorFactory validatorFactory = Validation.byDefaultProvider()
.configure()
.parameterNameProvider(new ReflectionParameterNameProvider())
.buildValidatorFactory();
return validatorFactory.getValidator();
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
final MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
return methodValidationPostProcessor;
}
单元测试
@RunWith(SpringRunner.class)
@WebMvcTest(ExampleController.class)
public class ExampleControllerTest {
private static final String EMPTY = "";
@Autowired
private MockMvc mvc;
@Test
public void test() throws Exception {
// Perform Request
ResultActions response = this.mvc.perform(
get("/example").param("userId", "invalid")
);
// Assert Result
response.andExpect(status().isBadRequest())
.andExpect(content().string(EMPTY));
}
}
但是,当我运行测试时,我得到200
而不是400
。当我作为应用程序运行时,不执行验证。
我认为可能是因为它在执行测试时没有拿起两个验证bean? 此验证有效
答案 0 :(得分:2)
@WebMvcTest
注释是在所谓的独立MockMvc配置之上的Spring Boot包装器。这个MockMvc功能测试独立控制器,没有任何其他bean。
为了能够测试更广泛的网络配置,您需要使用web application setup:
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration("my-servlet-context.xml")
public class MyWebTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
// ...
}
但请注意,此类Web应用程序设置并未提取所有Bean。例如,您需要显式注册Servler过滤器或Spring Security。但我认为应该包括验证。