测试LocalDateTime UTC方法

时间:2017-04-12 12:39:23

标签: java datetime junit

我有一个方法toUTC()

public ZonedDateTime toUTC(LocalDateTime ldt) {
   return ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC);
}

我想为这种方法编写一个测试,但我不确定最好的方法吗?有人能指出我正确的方向吗?我不是一个约会时间和时区专家

1 个答案:

答案 0 :(得分:1)

首先,您的方法无法编译。我得到了

  

类型不匹配:无法从ZonedDateTime转换为LocalDateTime

原则上,这很好,因为它允许我们至少一定程度的TDD:在方法之前(完成)编写测试。另一方面,当我们不确定该方法的要求时,编写测试是一项挑战。它应该返回当前签名所暗示的LocalDateTime,或者更确切地说是返回语句尝试的ZonedDateTime,或者可能是OffsetDateTime,因为我们知道目标偏移,甚至是Instant 1}},因为这些始终是UTC?

然而,我会将这个答案缩小到测试一个已经写好的方法,因为我认为这就是你所要求的。我假设返回类型为OffsetDateTime,方法如下:

public static OffsetDateTime toUTC(LocalDateTime ldt) {
    return ldt.atZone(ZoneId.systemDefault())
            .toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC);
}

下一个挑战是我们的方法取决于ZoneId.systemDefault()。这种依赖性降低了可测试性,因为我们希望测试在所有时区中运行,但该方法不应在所有时区中产生相同的结果。我没有搜索过操纵系统默认时区的方法,它们可能存在,并且有一些模拟框架可以让我们存根ZoneId.systemDefault()并控制它返回给我们方法的结果。我将在这里使用的简单方法是重构,解决了麻烦的依赖:

public static OffsetDateTime toUTC(LocalDateTime ldt) {
    return fromZoneToUtc(ldt, ZoneId.systemDefault());
}

static OffsetDateTime fromZoneToUtc(LocalDateTime ldt, ZoneId timeZone) {
    return ldt.atZone(timeZone).toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC);
}

我放弃测试上面第一个非常简单的方法,但测试第二个,所有逻辑发生的地方,现在可以使用常量数据完成,例如

    assertEquals(OffsetDateTime.of(2017, 4, 12, 14, 0, 0, 0, ZoneOffset.UTC),
            fromZoneToUtc(LocalDateTime.of(2017, 4, 12, 16, 0), ZoneId.of("Europe/Berlin")));

我会留给你找一些好的测试用例。我相信你可以想到一些不同的时区,一些区域有DST,有些区域没有。 UTC东部和西部的区域以及与UTC重合的区域(在测试年份时)。有些时候是在夏季,有些是在冬季,最好是一些接近DST交叉(春季和秋季)。

相关问题