40

我有一个 Spring MVC 控制器,它使用 Spring-Data 的分页支持:

@Controller
public class ModelController {

    private static final int DEFAULT_PAGE_SIZE = 50;

    @RequestMapping(value = "/models", method = RequestMethod.GET)
    public Page<Model> showModels(@PageableDefault(size = DEFAULT_PAGE_SIZE) Pageable pageable, @RequestParam(
            required = false) String modelKey) {

//..
        return models;
    }

}

我想使用漂亮的 Spring MVC 测试支持来测试 RequestMapping。为了使这些测试保持快速并与所有其他事情隔离开来,我不想创建完整的 ApplicationContext:

public class ModelControllerWebTest {
    private MockMvc mockMvc;

    @Before
    public void setup() {
        ModelController controller = new ModelController();
        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    public void reactsOnGetRequest() throws Exception {
        mockMvc.perform(get("/models")).andExpect(status().isOk());
    }

}

这种方法适用于其他不期望 Pageable 的控制器,但是通过这种方法,我得到了这些不错的长 Spring 堆栈跟踪之一。它抱怨无法实例化 Pageable:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.domain.Pageable]: Specified class is an interface
at   
.... lots more lines

问题:如何更改我的测试,以便神奇的 No-Request-Parameter-To-Pageable 转换正确发生?

注意:在实际应用中一切正常。

4

3 回答 3

50

Original answer:

The problem with pageable can be solved by providing a custom argument handler. If this is set you will run in a ViewResolver Exception (loop). To avoid this you have to set a ViewResolver (an anonymous JSON ViewResolver class for example).

mockMvc = MockMvcBuilders.standaloneSetup(controller)
            .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
            .setViewResolvers(new ViewResolver() {
                @Override
                public View resolveViewName(String viewName, Locale locale) throws Exception {
                    return new MappingJackson2JsonView();
                }
            })
            .build();

Updated (2020): It is not necessary to add the ViewResolver anymore.

Regarding the parallel answer: It does not solve the problem for the original question to have this test running without ApplicationContext and/or friends.

于 2014-03-04T20:04:55.313 回答
34

只需添加 @EnableSpringDataWebSupport 进行测试。而已。

于 2016-09-14T15:02:30.197 回答
12

对于春季启动,只需添加为我解决的 ArgumentResolvers :

从触发错误的代码:

this.mockMvc = MockMvcBuilders.standaloneSetup(weightGoalResource).build();

为此,它有效:

this.mockMvc = MockMvcBuilders.standaloneSetup(weightGoalResource)
            .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
            .build();
于 2018-08-25T08:43:06.347 回答