我有一个我序列化为 JSON 的案例类,以及一个检查往返工作的测试案例。
深埋在案例类中的是java.time.Instant
s,我将其放入 JSON 作为它们的纪元毫秒。
事实证明,anInstant
实际上具有纳秒精度,并且在翻译中丢失,导致测试失败,因为时间戳现在稍微偏离。
有没有一种简单的方法可以让 Scalatest 忽略差异?我只想修复测试,应用程序完全可以接受精度损失。
我有一个我序列化为 JSON 的案例类,以及一个检查往返工作的测试案例。
深埋在案例类中的是java.time.Instant
s,我将其放入 JSON 作为它们的纪元毫秒。
事实证明,anInstant
实际上具有纳秒精度,并且在翻译中丢失,导致测试失败,因为时间戳现在稍微偏离。
有没有一种简单的方法可以让 Scalatest 忽略差异?我只想修复测试,应用程序完全可以接受精度损失。
我们使用 Clock.instant 来知道当前时间,而不是 Instant.now 来避免这个问题。所以类的代码应该是这样的
class MyClass(clock: Clock) {
def getResult(): Result = {
Result(clock.instant)
}
}
在测试中,我们模拟 clock.instant 以保证我们检查的时间完全相同。
class MyClassTest {
val customTime = Instant.now
val clock = mock[Clock]
clock.instant() returns customTime
// test
val myClass = new MyClass(clock)
val expectedResult = Result(customTime)
myClass.getResult ==== expectedResult
}
我不确定它是否会对您的情况有所帮助,但以防万一以及其他任何人阅读:比较两个Instant
对象的正确方法只考虑毫秒和更粗略,是将每个对象截断到毫秒精度(在 Java 中):
Instant instant1 = Instant.parse("2018-12-14T08:25:54.232235133Z");
Instant instant2 = Instant.parse("2018-12-14T08:25:54.232975217Z");
if (instant1.truncatedTo(ChronoUnit.MILLIS).equals(instant2.truncatedTo(ChronoUnit.MILLIS))) {
System.out.println("Equal to the millisecond");
} else {
System.out.println("Not equal to the millisecond");
}
输出:
等于毫秒
如果您知道其中一个已经在其通过 JSON 的往返过程中被截断(并且您认为它必须是一个要求),那么您当然不需要再次截断那个。
使用 aClock
进行测试通常是一个好主意。它可以帮助您编写可重现的测试。你可以很容易地拥有一个只计算毫秒的时钟:
Clock c = Clock.tickMillis(ZoneOffset.UTC);
System.out.println(c.instant());
System.out.println(Instant.now(c));
刚才运行时的输出:
2018-12-14T10:48:47.929Z 2018-12-14T10:48:47.945Z
如您所见,生成的Instant
对象在秒上只有三位小数,即毫秒精度,没有更精细的了。当您只使用Clock
for drawingInstant
时,您传递到哪个时区都没有关系tickMillis
。