如何为独立MockMvc

时间:2018-03-07 20:25:18

标签: testng spring-test mockmvc spring-test-mvc

控制器

@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;
    }
}

我认为必须通过ConfigurableBeanFactoryConfigurableApplicationContext将其添加为bean后处理器。

1 个答案:

答案 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)