Mockito匹配SpringData findAll(Pageable)方法签名失败问题排查
解决Mockito Mock Spring Data MongoRepository findAll(Pageable)的编译错误
这个问题我之前也碰到过,核心原因是Java编译器在处理重载方法时,对Mockito参数匹配器的类型推断出了问题。让我们一步步拆解解决:
问题根源
Spring Data的MongoRepository继承自PagingAndSortingRepository,后者有两个重载的findAll方法:
Iterable<T> findAll(Sort sort)Page<T> findAll(Pageable pageable)
当你使用when(repo.findAll(any(Pageable.class)))时,编译器需要判断你要mock的是哪个方法。但由于any(Pageable.class)返回的是Matcher<Pageable>,泛型类型的擦除加上两个方法的参数都是接口,编译器错误地把它绑定到了findAll(Sort)方法上,于是就出现了那个令人困惑的错误提示。
解决方案1:使用doReturn替代when
Mockito的doReturn语法绕开了编译器对方法调用的类型检查,能更可靠地匹配到正确的重载方法。把你的代码改成这样:
Page<Idea> page = new PageImpl<>( IntStream.range(1, 10) .mapToObj(i -> Idea.builder().title("idea-" + i).build()) .collect(Collectors.toList())); // 用doReturn来mock,避免重载匹配问题 doReturn(page).when(repo).findAll(any(Pageable.class));
解决方案2:显式强制转换指定方法
如果你更习惯用when语法,可以通过强制转换Repository类型,明确告诉编译器要调用的是PagingAndSortingRepository中的findAll(Pageable)方法:
when(((PagingAndSortingRepository<Idea, ObjectId>) repo).findAll(any(Pageable.class))).thenReturn(page);
(注意把ObjectId换成你实际使用的实体ID类型)
关于自定义Repository方法的问题
你尝试自己定义findAll(Pageable)方法时出现的类型不匹配,本质上还是同一个问题——编译器依然无法正确推断匹配器对应的方法参数类型。用上面两种解决方案同样可以解决这个问题,不需要额外自定义方法,因为Spring Data已经为你提供了这个方法的实现。
内容的提问来源于stack exchange,提问作者Roberto Lo Giacco
相关产品推荐
相关产品推荐

