首页 > 解决方案 > 单元测试无法得到预期结果,代码如下

问题描述

这是我的代码,它将日期时间转换为纪元时间戳。逻辑是如果时间是本地日期时间,那么做某事,否则,做某事。成功案例效果不错

time_to_epoch(List(JString("2000-01-01"), JString("yyyy-MM-dd"))) shouldEqual JString("946684800")
time_to_epoch(List(JString("2013-09-29T18:46:19Z"), JString("yyyy-MM-dd'T'HH:mm:ss'Z'"))) shouldEqual JString("1380480379")

但是失败的情况不能得到预期的结果,错误是“java.time.format.DateTimeParseException: Text '2016-06-21-10-19-22' could not be parsed at index 19”,为什么我不能得到 JNothing?如何解决这个错误?</p>

time_to_epoch(List(JString("2016-06-21-10-19-22"), JString("YYYY-MM-dd-hh-mm-ss a"))) shouldEqual JNothing
def time_to_epoch(params: List[JValue]): JValue = params match {

      case _ :: _ :: Nil =>
        time_to_epoch(params ::: List(JString("UTC")))
      case a :: b :: c :: Nil =>

        val jdOpt = for {
          JString(timestamp) <- coerce.toString(a)
          JString(pattern) <- coerce.toString(b)

          formatter = DateTimeFormatter.ofPattern(pattern)
          df = formatter.parseBest(timestamp, LocalDateTime.from(_), LocalDate.from(_))

          jd1 <- if (df.isInstanceOf[LocalDateTime]) {
            val res = df.asInstanceOf[LocalDateTime].toInstant(ZoneOffset.of(String.valueOf(ZoneId.of("UTC").getRules.getOffset(LocalDateTime.now))))
            Try(JString(res.getEpochSecond.toString)).toOption
          } else {
            Try(JString(df.asInstanceOf[LocalDate].atStartOfDay(ZoneId.of("UTC")).toInstant.getEpochSecond.toString)).toOption
          }
        } yield jd1

        jdOpt.getOrElse(JNothing)
      case _ => JNothing
    }

标签: scala

解决方案


具体问题是异常被抛出在parseBest任何之外Try,所以它没有被捕获。

使用asInstanceOf也很危险,因此请match改用:

def time_to_epoch(params: List[JValue]): JValue = params match {
  case _ :: _ :: Nil =>
    time_to_epoch(params ::: List(JString("UTC")))
  case JString(timestamp) :: JString(pattern) :: JString(tz) :: Nil =>
    Try {
      val formatter = DateTimeFormatter.ofPattern(pattern)
      val df = formatter.parseBest(timestamp, LocalDateTime.from _, LocalDate.from _)

      df match {
        case ldt: LocalDateTime =>
          val res = ldt.toInstant(ZoneOffset.of(String.valueOf(ZoneId.of(tz).getRules.getOffset(LocalDateTime.now))))
          JString(res.getEpochSecond.toString)
        case ld: LocalDate =>
          JString(ld.atStartOfDay(ZoneId.of(tz)).toInstant.getEpochSecond.toString)
        case _ =>
          JNothing
      }
    }.getOrElse(JNothing)
  case _ =>
    JNothing
}

推荐阅读