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

时间:2018-12-13 15:20:34

标签: scala scalatest nanotime java.time.instant

我有一个序列化为JSON的case类,还有一个用于检查往返是否有效的测试用例。

深入java.time.Instant的案例类内部,我将它们放入JSON作为其时期毫秒。

结果是Instant actually has nanosecond precision并在翻译中迷失了方向,导致测试失败,因为现在的时间戳略有缩短。

是否有一种简单的方法可以使Scalatest忽略差异?我只想修复测试,精度损失对于应用程序是完全可以接受的。

2 个答案:

答案 0 :(得分:4)

我们使用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
}

答案 1 :(得分:2)

在比较之前截断为毫秒

我不确定这是否对您有帮助,但万一对于其他任何人,请继续阅读:比较两个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的往返中被截断的事实(并且您认为必须这样做),那么您当然不需要再次截断它。 / p>

使用仅具有毫秒精度的时钟

使用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绘制Instant时,传递给tickMillis的时区都没关系。