Mockito抛出InvalidUseOfMatchersException及UnsupportedOperationException问题
解决Mockito单元测试中的两类异常问题
一、InvalidUseOfMatchersException异常处理
针对when(myMapper.selectEntryByParameters(anyString(), anyString(), anyString(), anyString(), anyString(), any())).thenReturn(itemList)抛出的异常,核心原因是参数匹配器使用不符合规则,或mock对象处理逻辑冲突,可按以下步骤排查:
- 统一参数匹配规则:确保方法的所有参数要么全用匹配器(如
anyString()、any(XXX.class)),要么全用真实值,禁止混合使用。你当前用了6个匹配器,需确认selectEntryByParameters的参数数量和类型完全对应,建议把最后一个any()替换为具体类型的匹配器(比如any(Integer.class)),避免类型模糊导致的内部toString评估失败。 - 确认mock对象有效性:检查
myMapper是通过Mockito.mock(MyMapper.class)创建的纯mock对象,而非spy对象或真实实例(spy的匹配器使用规则不同)。 - 隔离mock关联对象:确保
prepareItem方法生成的itemList及其中的Item对象是完全初始化的普通实例,内部属性(如someIDs)未关联任何mock对象,避免触发mock的toString方法时出现评估异常。
二、UnsupportedOperationException(集合变为ImmutableCollection)处理
针对调用newItem.getSomeIDs().add(i)时的异常,核心是集合被转为不可变类型,可按以下步骤修复:
- 检查Item类的getter实现:确认
getSomeIDs()方法未返回不可变集合视图(比如return Collections.unmodifiableList(someIDs);),如果是这种情况,需修改getter返回原集合或可变副本。 - 返回对象深拷贝:在mock配置中,不要直接返回
prepareItem生成的原对象,而是返回其深拷贝,确保集合是独立的可变实例:Item clonedItem = new Item(item.getId(), new ArrayList<>(item.getSomeIDs()), ...); // 复制所有属性,集合用新ArrayList包装 when(myMapper.getItemById(anyString())).thenReturn(clonedItem); - 排查代理/包装逻辑:如果是Spring环境下的测试,确认是否使用了
@SpyBean或AOP代理,这类逻辑可能会自动包装集合为不可变类型,可尝试改用纯Mockito mock(Mockito.mock)替代Spring整合的mock。
内容的提问来源于stack exchange,提问作者Heribert Greinix
相关产品推荐
相关产品推荐

