在 ScalaTest 中比较 OffsetDateTime 和时间戳
Comparing OffsetDateTime to Timestamp in ScalaTest
我是 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
有什么想法吗?我正在考虑实现一个自定义匹配器,但被困住了
尝试像这样将它们都转换为 Long
值
val expected = OffsetDateTime.parse(offsetDateTimeValue, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toInstant.toEpochMilli
val actual = timestampValue.toInstant(ZoneOffset.UTC).toEpochMilli
expected shouldBe actual
自定义相等解决方案-
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)
如果您有一堆 time-related 测试,这种方法可以避免每次都进行转换。主要的缺点是,你显然不能选择性地覆盖相等性只有在你比较的东西是时间戳的情况下,如果你想以相反的方式进行比较,你还必须实现一个Equality[Timestamp]
.
我最终实现了自定义匹配器,因为我在很多测试中都需要它
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)
我是 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
有什么想法吗?我正在考虑实现一个自定义匹配器,但被困住了
尝试像这样将它们都转换为 Long
值
val expected = OffsetDateTime.parse(offsetDateTimeValue, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toInstant.toEpochMilli
val actual = timestampValue.toInstant(ZoneOffset.UTC).toEpochMilli
expected shouldBe actual
自定义相等解决方案-
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)
如果您有一堆 time-related 测试,这种方法可以避免每次都进行转换。主要的缺点是,你显然不能选择性地覆盖相等性只有在你比较的东西是时间戳的情况下,如果你想以相反的方式进行比较,你还必须实现一个Equality[Timestamp]
.
我最终实现了自定义匹配器,因为我在很多测试中都需要它
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)