【问题标题】:Isolated Controller Test can't instantiate Pageable隔离控制器测试无法实例化可分页
【发布时间】:2014-04-06 03:33:19
【问题描述】:

我有一个 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 转换正确发生?

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

【问题讨论】:

    标签: spring-mvc testing spring-data spring-mvc-test


    【解决方案1】:

    原答案:

    pageable 的问题可以通过提供自定义参数处理程序来解决。如果设置了此项,您将在 ViewResolver 异常(循环)中运行。为避免这种情况,您必须设置一个 ViewResolver(例如匿名 JSON ViewResolver 类)。

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

    更新(2020 年): 无需再添加ViewResolver

    关于平行答案: 在没有ApplicationContext 和/或朋友的情况下运行此测试并不能解决原始问题的问题。

    【讨论】:

      【解决方案2】:

      只需添加@EnableSpringDataWebSupport 进行测试。就是这样。

      【讨论】:

      • 我在测试类中添加了@EnableSpringDataWebSupport 注释,但这没有任何效果。你能否提供更多关于这应该如何工作的细节? -1 现在
      • 应该是正确答案。如果您的单元测试仍然失败,请检查返回的错误是否不同。可能你已经转移到另一个错误。
      • 为什么这样有效?您能否提供更多解释,以便我可以更好地理解如何在再次发生时克服这种情况? :-)
      • 将 @EnableSpringDataWebSupport 添加到测试类并不能解决我的问题 - 仍然是同样的例外:No primary or default constructor found for interface org.springframework.data.domain.Pageable。这是否依赖于某些包?
      • Sooo.... 我不得不删除 @DataJpaTest 并将 BackendApplication 上一层。
      【解决方案3】:

      对于 Spring Boot,只需添加为我解决的 ArgumentResolvers:

      来自触发错误的代码:

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

      对此,有效:

      this.mockMvc = MockMvcBuilders.standaloneSetup(weightGoalResource)
                  .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
                  .build();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-10
        • 2019-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-11
        相关资源
        最近更新 更多