用Mockito为ExternalQueryBuilder写单元测试遇Object转List的类转换异常
类转换异常的根因
- 本次抛出的
java.lang.ClassCastException和Mockito框架无直接关系,核心是测试入参的类型和被测方法的实际处理逻辑不匹配:- 被测的
buildQuery方法在处理dataSourceType字段时,明确将从Map中取出的值强转为List<String>类型:List<String> dataSourceType = (List<String>) request.get("dataSourceType"); - 你在测试代码中为
dataSourceType键存入的是Mockito.mock(Object.class)生成的普通Object实例,并非List类型,因此执行强转逻辑时必然触发类型转换失败。
- 被测的
- 测试代码中存在完全无效的Mock操作:你在测试方法内创建的
Mockito.mock(StringBuilder.class)实例从未被被测方法引用——被测方法内部自行初始化了StringBuilder对象,外部mock的实例不会参与到方法执行流程中,没有任何实际作用。
修正方案
- 调整测试入参的构造逻辑,确保存入Map的值和被测方法的类型预期匹配
dataSourceType键对应的值直接使用真实的List<String>实例即可(这类简单值对象无复杂依赖,不需要用Mockito mock),比如构造List.of("数据源类型值")传入dataElement键对应的值直接使用符合拼接逻辑的字符串即可,不需要刻意mock普通Object实例
- 删除测试代码中无意义的mock语句,避免增加无效代码
- 调用被测方法后可对拼接生成的查询串做断言,验证逻辑是否符合预期,而非仅执行方法不做结果校验。
修正后的测试代码示例
public void buildQueryTest(){ Map<String, Object> request = new HashMap<>(); // 匹配字段预期的dataElement值 request.put("dataElement", "测试数据元素"); // 匹配强转要求的List<String>类型dataSourceType值 request.put("dataSourceType", List.of("内置数据源")); String queryResult = externalQueryBuilder.buildQuery(request); // 后续可增加对queryResult的断言,验证拼接逻辑正确性 }
注意:
Map<String, Object>的泛型定义仅代表Map允许存储任意类型的对象,不代表存入的所有对象都能通过后续的强转逻辑,构造测试参数时需要对照被测代码的实际类型处理逻辑,匹配对应类型后再存入,避免触发不必要的类转换异常。
单元测试中对于String、ArrayList这类简单的值对象,优先使用真实实例即可,不需要刻意用Mockito模拟,除非需要验证这些对象的特殊行为(比如方法调用、抛出特定异常等)。
内容的提问来源于stack exchange,提问作者Gregory Javis
相关产品推荐
相关产品推荐

