我应该为依赖specs
并以Scala
编写的基础实现的库的集成测试做出贡献。该测试更绑定到具有某些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
被另一个类覆盖/包装。>
答案 0 :(得分:5)
有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