4

我有一个我序列化为 JSON 的案例类,以及一个检查往返工作的测试案例。

深埋在案例类中的是java.time.Instants,我将其放入 JSON 作为它们的纪元毫秒。

事实证明,anInstant实际上具有纳秒精度,并且在翻译中丢失,导致测试失败,因为时间戳现在稍微偏离。

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

4

2 回答 2

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
}
于 2018-12-13T15:43:14.540 回答
4

在比较之前截断到毫秒

我不确定它是否会对您的情况有所帮助,但以防万一以及其他任何人阅读:比较两个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对象在秒上只有三位小数,即毫秒精度,没有更精细的了。当您只使用Clockfor drawingInstant时,您传递到哪个时区都没有关系tickMillis

于 2018-12-14T08:44:24.693 回答