【问题标题】:How to resolve side effect rising from LocalDate in tests (scala)?如何解决测试(scala)中从 LocalDate 上升的副作用?
【发布时间】:2021-02-03 14:14:53
【问题描述】:

我有一个函数可以将时间以毫秒为单位转换为 LocalDate 对象:

def convertToLocalDateTimeViaInstant(dateToConvert: java.util.Date): java.time.LocalDate =
    dateToConvert.toInstant.atZone(ZoneId.systemDefault).toLocalDate

我对此函数进行了单元测试,如下所示:

 "convertToLocalDateTimeViaInstant" should {
    "return the correct LocalDate instance" in new SAMLServiceTestEnv() {
      val timeInMillis: Long = 1349333576093L // Date is Thu Oct 04 2012 06:52:56 UTC in millis
      val someDate = new Date(timeInMillis) 
      val resultDate: LocalDate = samlServiceImpl.convertToLocalDateTimeViaInstant(someDate)
      
      resultDate.getYear mustEqual 2012
      resultDate.getMonth mustEqual java.time.Month.OCTOBER
      resultDate.getDayOfMonth mustEqual 4
    }
  }

当我单独运行这个测试或整个文件时,这个测试会做出正确的断言。值1349333576093L 对应于Thu Oct 04 2012 06:52:56 UTC 和Wed Oct 03 2012 23:52:56 PST(旧金山时间)。

但是,当我在项目中运行所有单元测试时,我发现此测试失败。 resultDate.getDayOfMonth mustEqual 4 断言未能声明 4 is not equal to 3。我很惊讶地看到这一点,因为该函数在单独运行时清楚地考虑了 UTC 时间,但在一起运行时以某种方式观察了本地时间?我在这里做错了什么?

【问题讨论】:

    标签: scala scalatest localdate


    【解决方案1】:

    标准做法是不直接使用LocalDate.now()。就像,完全一样。您有一些ClockTimer 为您提供当前时间,如果您需要在时间很重要的情况下进行任何测试 - 您只需存根此当前时间提供程序以将时间固定为某个值。并且您从测试中完全消除了时间依赖性。无论您希望看到它多么“实用”,任何其他方法都会被设计破坏。

    事实上,Clock 是 JDK 8 中的内置组件:https://docs.oracle.com/javase/8/docs/api/java/time/Clock.html,因此您甚至不必引入新的依赖项。

    【讨论】:

    • 我会听从你说的,除非我找不到没有now() 的方法不这样做 - 我的代码检查日期即将到期的位置,我需要now() 进行比较。你会如何建议我这样做?即使我确实使用Clock 来获取当前日期/时间,我如何使用自定义LocalDate 对象?
    • clock.instant() 返回当前的Instant (Instant.now()),可以是translatedLocalDate。因此,您只需编写一个实用程序,该实用程序接受 Clock 获取 Instant 并将其转换为 LocalDate 并且您有一个可以模拟的灵活 LocalDate.now() 替换。
    猜你喜欢
    • 2012-07-22
    • 2018-03-14
    • 2011-05-28
    • 2012-07-18
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    相关资源
    最近更新 更多