1

据推测,我正在为依赖于specsScala. timestamp测试更多地绑定到带有某些属性的事件流。

以下存根是实际实现的一部分

private def eligibleForRecentPost(optionalPost: Option[SearchEntity]): Boolean = {
    optionalSearch.map(search => search.timestamp)
      .exists(searchTime => searchTime >= LocalDateTime.now()
        .minusDays(recencyDurationInDays).atZone(ZoneId.systemDefault).toInstant.toEpochMilli)
}

现在,我要查找的代码可能类似于

// just a mock
when(LocalDateTime.now().minusDays(any)
    .atZone(ZoneId.systemDefault).toInstant.toEpochMilli)
    .thenReturn(1579625874972)

请注意,我知道测试中的 search.timestamp 可以更新,但这需要在每个recencyDurationInDays!!

但是在specs2和/或scala中有没有更好更可靠的方法来做到这一点?

编辑:我必须提到,我不期待改变实现,以便LocalDateTime被另一个类覆盖/包装。

4

1 回答 1

6

有像powermock这样的工具允许这样的事情。但它们是最后的解决方案,如果你必须在你无法控制的代码中模拟一些东西。

通常,您会改为执行以下操作:

trait Clock {

  def now(): LocalDateTime  
}

class DefaultClock extends Clock {

  def now(): LocalDateTime = LocalDateTime.now()
}

然后将Clock实例注入到使用它的代码中。

您可以只传递一个执行您想要的任何操作的实例,而不是模拟静态方法:

val simulatedNow = ... // calculate the right date for now
val clock = new Clock {
  def now() = simulatedNow
}
// inject clock
// run code and check assertion
于 2020-05-05T12:17:58.233 回答