Spring测试中Instant类型时间assertEquals断言失败问题求助
问题:Instant时间戳断言失败,本地与同事环境表现不一致
我有一项测试用例,在同事的环境中均可正常运行,但在我的环境中失败。测试逻辑为获取两个不同实体的Instant类型时间戳,通过assertEquals断言二者相等——从业务逻辑来看二者应该一致,但断言始终失败。
相关代码
assertEquals(notUpdatedRule.getModStamp(), rule.getModStamp());
报错信息
org.opentest4j.AssertionFailedError: Expected :2023-01-22T19:46:20.754829Z Actual :2023-01-22T19:46:20.754829486Z
我已将OpenJDK版本调整为与同事一致,但问题仍未解决。
原因分析
从报错信息可以看出,两个Instant对象的时间精度不一致:一个是微秒级(保留6位小数),另一个是纳秒级(保留9位小数)。Instant的equals方法会严格校验到纳秒级别,因此哪怕时间的核心部分一致,精度差异也会导致断言失败。
同事环境正常的原因,大概率是他们的环境中时间戳在生成、存储或序列化环节被截断到了微秒精度,而你的环境保留了完整的纳秒精度。
解决方案
1. 调整断言逻辑,忽略精度差异
如果业务上不需要校验纳秒级精度,可以修改断言方式:
- 用AssertJ提供的专用断言(推荐):
assertThat(notUpdatedRule.getModStamp()).isEqualToIgnoringNanos(rule.getModStamp()); - 手动截断到统一精度,兼容JUnit原生断言:
Instant expected = notUpdatedRule.getModStamp().truncatedTo(ChronoUnit.MICROS); Instant actual = rule.getModStamp().truncatedTo(ChronoUnit.MICROS); assertEquals(expected, actual);
2. 排查环境中时间精度的差异点
如果需要保持和同事一致的精度,检查以下环节:
- 数据库存储:比如MySQL中
DATETIME字段的精度,DATETIME(6)对应微秒,DATETIME(9)对应纳秒,确认你的表结构和同事一致。 - ORM框架配置:比如Hibernate的
@Column(precision = 6)注解,是否设置了相同的时间精度。 - 序列化/反序列化配置:比如Jackson的
jackson.datatype.jsr310.serialization.write-date-timestamps-with-nanoseconds参数,是否和同事的配置一致。
内容的提问来源于stack exchange,提问作者Fabian Lüdicke
相关产品推荐
相关产品推荐

