控制器
@RestController
@Validated
class MyController {
@GetMapping("/foo")
public String unwrapped(@Min(1) @RequestParam("param") int param) {
return Integer.toString(param);
}
@GetMapping("/bar")
public String wrapped(@ModelAttribute @Valid Wrapper bean) {
return Integer.toString(bean.param);
}
static class Wrapper {
@Min(1)
int param;
public void setParam(final int param) {
this.param = param;
}
}
}
测试
public class MyControllerTest {
MyController controller = new MyController();
MockMvc mockMvc = MockMvcBuilders
.standaloneSetup(this.controller)
.build();
@Test // fails
public void unwrapped() throws Exception {
this.mockMvc.perform(get("/foo")
.param("param", "0"))
.andExpect(status().isBadRequest());
}
@Test // passes
public void wrapped() throws Exception {
this.mockMvc.perform(get("/bar")
.param("param", "0"))
.andExpect(status().isBadRequest());
}
}
要在春季启用(解包)方法参数验证,必须使用@Validated
注释控制器,并且必须将MethodValidationPostProcessor
添加到上下文中。
是否可以将MethodValidationPostProcessor
bean添加到独立设置中?
问题可能会减少到如何将BeanPostProcessor
添加到独立的MockMvc设置中?
Sam Brannen推荐的解决方案无济于事:
MockMvc mockMvc = new MyStandaloneMockMvcBuilder(this.controller).build();
// . . .
static class MyStandaloneMockMvcBuilder extends StandaloneMockMvcBuilder {
MyStandaloneMockMvcBuilder(final Object... controllers) {
super(controllers);
}
@Override
protected WebApplicationContext initWebAppContext() {
WebApplicationContext context = super.initWebAppContext();
ReflectionTestUtils.invokeMethod(context, "addBean", "methodValidationPostProcessor", new MethodValidationPostProcessor());
return context;
}
}
我认为必须通过ConfigurableBeanFactory
或ConfigurableApplicationContext
将其添加为bean后处理器。
答案 0 :(得分:1)
是否可以将
MethodValidationPostProcessor
bean添加到独立设置中?
不,遗憾的是,在使用MockMvcBuilders.standaloneSetup()
时无法实现这一点,因为这会在幕后创建StubWebApplicationContext
不支持BeanPostProcessor
。
一旦SPR-6380被解决(目前在Spring Framework 5.x积压中),您将不再需要依赖MethodValidationPostProcessor
。但是,在此期间,您需要切换到使用MockMvcBuilders.webAppContextSetup()
,以便能够通过MethodValidationPostProcessor
测试添加到控制器的行为。
我认为不可能直接这样做;但是,您可以创建 StandaloneMockMvcBuilder
的自定义子类来覆盖initWebAppContext()
方法,委托super.initWebAppContext()
创建WebApplicationContext
,然后注册MethodValidationPostProcessor
bean以编程方式通过org.springframework.test.web.servlet.setup.StubWebApplicationContext.addBean(String, Object)
。