
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
昆明达内培训的老师给大家讲Junit mockito测试Controller层方法有Pageable异常。
1、问题
在使用MockMVC+Mockito模拟Service层返回的时候,当我们在Controller层中参数方法调用有Pageable对象的时候,我们会发现,我们没办法生成一个Pageable的对象,会报一个Pageable是一个接口的错误。当我们把所有的参数从Pageable接口变成Pageable的实现类PageRequest的时候,所有的方法参数都换成PageRequest,又会出现一个新的错误,且不说PageRequest不能作为参数用于hibernate的分页查询,另一方面,它没有构造方法,也无法初始化。
2、代码
1)controller代码,主要是
@RequestMapping("/banners")
public DataMap showBanners(BannerQuery bannerQuery, @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
Page<Banner> page = bannerService.findPage(bannerQuery, pageable);
return new DataMap().addAttribute(Constants.STATUS_CODE, StatusCode.SUCCESS.getStatusCode())
.addAttribute(Constants.DATA, page);
}
2)测试方法:
@Test
public void showBannersWithWhenTest() throws Exception {
Banner banner = new Banner();
banner.setBannerUrl("www.baidu.com");
banner.setActionUrl("hhtp");
List<Banner> list = new ArrayList<>();
list.add(banner);
Page<Banner> page = new PageImpl<Banner>(list);
when(bannerService.findPage(isA(BannerQuery.class),isA(Pageable.class))).thenReturn(page); //mock绑定了放回
//生成一个发送请求的类
RequestBuilder rb = get("/banners") //请求的url
.param("page","0") //请求的参数
.param("size","5")
.contentType(MediaType.APPLICATION_FORM_URLENCODED);
String responseString = mockMvc.perform(rb)
.andDo(print()) //添加ResultHandler结果处理器,比如调试时打印结果到控制台
/* .andExpect(jsonPath("$.data.content").isArray()) //判断返回的数据是否是一个数组*/
.andExpect(status().isOk()) //判断返回的状态是否为200
/*.andExpect(jsonPath("$.data.content",hasSize(5))) //判断返回的json对象的data.content属性的大小是否为5
//判断返回的data.content中的第一个对象的uid属性是否为所给值
.andExpect(jsonPath("$.data.content[0].uid",is("81377051ddb6424fa677931ab1bc6496")))
.andExpect(jsonPath("$.data.content[1].uid",is("8cb7b04fdea846d2ab6006fa1280a8b8")))*/
.andReturn().getResponse().getContentAsString();
System.out.println("--------showCategorysTest()返回的json = " + responseString);
}
3)报错:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.domain.Pageable]: Specified class is an interface
3、解决方法:
报错的原因:没有Pageable的解析器。
解决的方法:给他设置一个解析器
1)使用匿名内部类
@Before()
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(bannerController).setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
.setViewResolvers(new ViewResolver() {
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return new MappingJackson2JsonView();
}
} )
.build();
}
2)通过注解的方式注入一个PageableHandlerMethodArgumentResolver解析器
@InjectMocks
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
@Before()
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(bannerController).setCustomArgumentResolvers(pageableArgumentResolver)
.build();
}
了解详情请登陆昆明达内IT培训官网(km.tedu.cn)!