应使用基本类型断言和delta容差比较浮点数,避免包装类引用比较;整数优先用基本类型断言防缓存干扰;对可能为null的包装类需先非空校验;推荐AssertJ提升可读性与空安全性。

直接用基本类型断言,别用包装类比较数值结果。
用 assertEquals(double, double, delta) 替代 assertEquals(Double, Double)
包装类的 equals() 比较的是对象引用或精确值(对 Double 还涉及 NaN、-0.0 等边界),而浮点计算天然存在精度误差。JUnit 的 assertEquals(double expected, double actual, double delta) 才是专为浮点数设计的安全比对方式。
- ✅ 正确写法:
assertEquals(3.14159, result, 1e-6); - ❌ 危险写法:
assertEquals(Double.valueOf(3.14159), Double.valueOf(result));—— 可能因二进制表示差异失败 - ⚠️ 注意:即使
result是Double类型,也应先解包:assertEquals(3.14159, result.doubleValue(), 1e-6);
整数计算优先用基本类型断言,避免自动装箱干扰
Integer、Long 等在 -128~127 范围内会缓存实例,超出范围则每次 new 出新对象。用 equals() 断言可能因缓存机制偶然通过,掩盖逻辑缺陷;用 == 更不可靠。
- ✅ 推荐:
assertEquals(42, result.intValue());或直接assertEquals(42, result);(JUnit 会自动解包) - ❌ 避免:
assertEquals(Integer.valueOf(42), result);(语义不清,依赖缓存) - ? 小技巧:若方法返回
Integer,测试中可显式调用.intValue()再断言,逻辑更透明
警惕 null 包装类导致 NPE 或静默失败
如果被测代码可能返回 null 的包装类(如 Optional<integer>.orElse(null)</integer>),直接调用 .intValue() 会抛 NullPointerException;而 assertEquals(null, result) 又无法验证数值逻辑。
立即学习“Java免费学习笔记(深入)”;
- ✅ 安全做法:先断言非空,再断言值:
assertNotNull(result); assertEquals(100, result.intValue()); - ✅ 或使用 Optional 风格断言:
assertTrue(result != null && result == 100);(简洁且无 NPE) - ⚠️ 不要用
assertEquals(100, result)当result可能为null—— JUnit 5 会报错,JUnit 4 可能静默失败
统一用 AssertJ 提升可读性与健壮性
AssertJ 的 fluent API 天然规避包装类陷阱,例如 isEqualTo() 对数字类型自动做数值比较,不依赖 equals(),还支持 isCloseTo() 精确控制浮点容差。
- ✅ 浮点:
assertThat(result).isCloseTo(3.14159, within(1e-6)); - ✅ 整数:
assertThat(result).isEqualTo(42);(无论result是int、Integer或long) - ✅ 空安全:
assertThat(result).hasValue(100);(隐含非空 + 值匹配)
不复杂但容易忽略:断言的本质是验证行为,不是验证对象身份。数值结果就该按数值逻辑比对,包装类只是载体,不该让它干扰判断。


















