ScalaTest:在同一毫秒内,将Instants视为相等



我有一个将其序列化为JSON的用例类,以及一个检查往返是否有效的测试用例。

隐藏在case类内部的是java.time.Instants,我将其作为epoch毫秒放入JSON中。

事实证明,Instant实际上具有纳秒的精度,而这在翻译中会丢失,导致测试失败,因为时间戳现在稍微偏离了。

有没有一种简单的方法可以让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的往返过程中被截断(并且您认为这是必须的(,那么您当然不需要再次截断那个。

使用只有毫秒预置的时钟

使用Clock进行测试通常是个好主意。它可以帮助你编写可重复的测试。你可以很容易地拥有一个只计数毫秒的时钟:

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绘制Instants,则传递给tickMillis的时区并不重要。

相关内容

  • 没有找到相关文章

最新更新