Mockito单元测试调用doOperation返回Iterable时出现WrongTypeOfReturnValue错误
问题原因
该异常是Mockito Stub逻辑被干扰导致的,核心触发原因如下:
- 你Mock的是
ClientWrapperImpl实现类而非ClientWrapper接口,使用when(obj.method()).thenReturn()语法Stub类类型的Mock对象时,会先执行一次真实的doOperation方法,真实方法执行过程中的内部逻辑打乱了Mockito的Stub上下文,导致框架误将你设置的Iterable类型返回值当成了toString()方法的返回值,最终抛出类型不匹配错误。 - 你提供的测试代码存在语法笔误:
Mockito.when(documentIterable.iterator)).thenReturn(documentIterator);中多了一个多余的右括号,也可能导致Stub逻辑异常。 - 额外的不合理Mock逻辑:手动Mock
Iterable和Iterator属于不必要的操作,迭代器的Mock逻辑很容易出现遗漏,进一步增加出错概率。
解决方案
你可以选择以下任意一种方案修复,也可以组合使用优化测试代码:
- 改用
doReturn系列方法Stub,避免触发真实方法执行
将原Stub代码
替换为Mockito.when(mocClientWrapper.doOperation(Mockito.anyList())).thenReturn(documentIterable);
该语法不会触发真实方法执行,从根源避免上下文被干扰的问题。Mockito.doReturn(documentIterable).when(mocClientWrapper).doOperation(Mockito.anyList()); - 改为Mock
ClientWrapper接口而非实现类
接口类型的Mock对象不会触发真实方法执行,原来的when().thenReturn()写法即可正常运行。 - 去掉不必要的Mock逻辑,用真实集合类构造返回值
List本身就实现了Iterable接口,你可以直接用JDK自带的集合类构造返回值,完全不需要手动Mock迭代器逻辑,修改后的代码更简洁也更不容易出错:Document mockDocuent=Mockito.mock(Document.class); Iterable<Document> documentIterable = Collections.singletonList(mockDocuent); - 检查测试类注解配置
确保测试类上添加了对应版本的Mockito启动注解:Junit4添加@RunWith(MockitoJUnitRunner.class),Junit5添加@ExtendWith(MockitoExtension.class),保证@Mock注解能正常生效。
内容的提问来源于stack exchange,提问作者JSS
相关产品推荐
相关产品推荐

