测试泛型业务逻辑应聚焦擦除后对象的行为与内容:验证集合类型、元素类型转换、字段值、异常路径及边界输入,避免测试泛型声明本身,用真实调用替代类型假设。

测试带有泛型的复杂业务逻辑,核心不是验证“泛型声明是否还在”,而是确认擦除后实际运行对象的行为、结构和内容是否符合业务预期。Java 泛型在运行时已擦除,List
关注返回对象的真实类型与内容
泛型擦除后,集合本身仍是 ArrayList 或 LinkedList 等具体类型,内部元素是 Object,但业务代码中它们本应是 Order、Product 等具体类。测试时要验证:
- 返回值非 null,且是预期的具体集合类型(如 instanceof ArrayList)
- 集合 size() 正确,每个元素能安全转型为对应业务类型(如 element instanceof Order)
- 关键字段值符合预期(如 order.getStatus() == "PAID"、product.getPrice() > 0)
- 若业务对象重写了 equals/hashCode,可用 assertEquals 验证整个集合内容一致性
覆盖空值、异常和边界输入场景
泛型方法常因参数非法或数据缺失而返回 null、空集合或抛异常,这些必须显式断言:
- 用 assertNull() 检查 Optional
或直接返回值为空的情况(如查询不存在订单 ID) - 用 assertThrows() 验证非法参数触发的异常(如传入 null 分页参数导致 IllegalArgumentException)
- 测试空列表、单元素列表、含 null 元素的列表,确认业务逻辑不崩溃(例如 map 处理时是否 NPE)
- 对分页、排序、过滤等复杂操作,分别验证第一页、最后一页、无结果等典型状态
避免测试泛型声明本身
以下做法没有意义,也不反映真实行为:
- 不用 instanceof 判断 List
—— 编译不通过,只能写 instanceof List - 不依赖反射读取 getGenericReturnType 来断言泛型签名 —— 这测的是编译器行为,不是业务逻辑
- 不用 assertSame 比较两个泛型集合 —— 地址不同就失败,且忽略内容语义
- 不写 new ArrayList
() 与返回值做 assertEquals —— 擦除后类型一致但内容不同仍报错,且掩盖了真正要验证的业务数据
用真实业务调用代替类型假设
与其纠结“它是不是 List
- 拿到返回的 list 后,遍历调用 order.getOrderId()、order.getItems().size() 等方法,看是否抛 ClassCastException
- 把 list 传给下游服务方法(如 sendToKafka(List
orders)),确认不因类型不匹配而编译失败或运行异常 - 如果方法返回 Map
>,就验证 map.containsKey("header")、map.get("header").get(0).getAmount() 是否合理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











