单元测试mock Label的UUID时报UUID cannot be returned by toString()错误如何解决
问题根因
- 你没有使用Mockito生成的代理对象,直接new了原生
Label实例。Mockito的when()打桩逻辑仅对代理对象的方法调用生效,原生对象调用getUuid()会直接返回真实的UUID值,而非Mockito可识别的方法调用占位符,框架无法匹配到你要打桩的getUuid()方法,才会误匹配到最近一次调用的toString()方法,抛出类型不匹配错误。 - 父类
BaseEntity中的uuid字段被final修饰,若getUuid()方法也为final修饰,默认的Mockito配置无法拦截该方法的调用,也会导致打桩失败。
修复方案
你可以根据自己的测试场景二选一:
方案1:使用Mock代理对象打桩
- 首先将创建Label的逻辑改为生成Mockito代理对象:
UUID uuid = UUID.randomUUID(); for (int i = 0; i < list.size(); i++) { // 替换new Label()为Mock代理对象 Label label = Mockito.mock(Label.class); when(label.getUuid()).thenReturn(uuid); // 其他业务逻辑 }
- 如果修改后打桩仍不生效,说明
getUuid()方法是final修饰,需要开启Mockito的final方法支持:在测试资源目录test/resources下新建mockito-extensions/org.mockito.plugins.MockMaker文件,文件内容写入mock-maker-inline即可。
方案2:反射修改真实对象的uuid值(推荐,无需额外配置)
如果你的测试场景需要保留Label对象其他方法的真实逻辑,可直接通过反射修改父类的final字段值,无需使用Mock:
UUID mockUuid = UUID.randomUUID(); Label label = new Label(); // 反射修改final uuid字段 Field uuidField = BaseEntity.class.getDeclaredField("uuid"); uuidField.setAccessible(true); uuidField.set(label, mockUuid);
这个方案不需要依赖Mockito的打桩能力,也不会影响Label其他方法的正常执行,更适合实体类的单测场景。
提示:反射调用时需要处理对应的检查异常,直接在测试方法上添加
throws Exception声明即可,无需额外捕获处理。
内容的提问来源于stack exchange,提问作者user16979464
相关产品推荐
相关产品推荐

