我在Scala世界中很陌生
在我的Scala测试中,我有java.time.OffsetDateTime和java.sql.Timestamp
offsetDateTimeValue shouldBe timestampValue
结果:
Expected :2019-06-20T16:19:57.988Z
Actual :2019-06-20 16:19:57.988
有什么想法吗?我当时在考虑实现自定义匹配器,但被困住了
答案 0 :(得分:2)
尝试将它们都转换为Long
值
val expected = OffsetDateTime.parse(offsetDateTimeValue, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toInstant.toEpochMilli
val actual = timestampValue.toInstant(ZoneOffset.UTC).toEpochMilli
expected shouldBe actual
答案 1 :(得分:2)
自定义平等解决方案-
implicit val timeEquality : Equality[OffsetDateTime] = (a: OffsetDateTime, b: Any) => b match {
case timestamp: Timestamp => a.toInstant == timestamp.toInstant // can also go via epoch milliseconds as per Mario's solution
case other => a == other
}
val instant = Instant.now()
val offset = OffsetDateTime.ofInstant(instant, ZoneId.of("UTC"))
val timestamp = Timestamp.from(instant)
offset shouldEqual timestamp // test passes
使用equal
/ shouldEqual
代替be
,可以实现Equality
并将其作为隐式参数传递,从而自定义匹配器使用的相等性。如果您不喜欢隐式,也可以显式传递它:
val timesBeingEqual: Equality[OffsetDateTime] = ...
(offset shouldEqual timestamp)(decided by timesBeingEqual)
如果您有许多与时间相关的测试,则此方法无需每次转换。主要缺点是,显然,只有在您要与之进行比较的对象是时间戳的情况下,您才能选择性地覆盖相等性,并且如果您要进行比较,则还必须实现一个Equality[Timestamp]
。
答案 2 :(得分:2)
由于在许多测试中都需要自定义匹配器,所以我最终实现了该匹配器
def beTheSameDate(right: OffsetDateTime) = DateTestMatcher(right)
case class DateTestMatcher(right: OffsetDateTime) extends Matcher[Timestamp] {
override def apply(left: Timestamp): MatchResult = {
val areEqual = left.toLocalDateTime == right.toLocalDateTime
MatchResult(areEqual, "Dates are not equal", "Dates are equal")
}
然后
timestampValue should beTheSameDate(offsetDateTimeValue)