gpt4 book ai didi

java - 使用 Java 8 Date/Time 类编写和测试便捷方法

转载 作者:行者123 更新时间:2023-12-02 10:40:22 25 4
gpt4 key购买 nike

我有一些使用日历编写的旧的便捷方法,我想更新它们以使用 Java 8 中引入的 Java.time.* 类。我的类中的一些方法获取诸如当前时间之类的数量,甚至只是当前时间。

我计划为每种方法编写两种变体:一种假设时区是这台计算机上定义的默认时区,另一种允许用户指定所需的时区。

我试图弄清楚两件主要事情:

  1. 如何在我的方法中获取当前时间戳。
  2. 如何使用当前时间戳的不同源对我的结果进行单元测试。

关于方法本身,我倾向于创建一个 ZonedDateTime,如下所示:

LocalDateTime currentDateTime = LocalDateTime.now();
ZoneId timeZoneDefault = ZoneId.systemDefault();
ZonedDateTime currentZonedDateTimeDefault = ZonedDateTime.of(currentDateTime, timeZoneDefault);

然后,我将使用 DateTimeFormatter 来获取我真正关心的结果部分。例如,如果我想要从 24 小时制获取当前时间,然后从 12 小时制获取当前时间,我会这样做:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("kk");
System.out.println("currentHour (24 hour clock): " + currentZonedDateTimeDefault.format(fmt));
DateTimeFormatter fmt2 = DateTimeFormatter.ofPattern("hh a");
System.out.println("currentHour (12 hour clock): " + currentZonedDateTimeDefault.format(fmt2));

到目前为止还可以吗?或者我应该使用不同的方法,也许使用 Instant?

我的主要问题是找到一种不同的方法来获取单元测试的当前时间,以便我可以将预期结果与实际结果进行比较。我一直在阅读有关时钟和瞬间等的内容,读得越多,我就越感到困惑。有些方法似乎是从同一来源获取当前时间,因此它们可能会表明预期结果始终与实际结果相同 - 但两者都可能以相同的方式出错。

有人可以指导我计算给定时区当前时间的最佳方法,该方法以与我在方法中使用的方式不同的方式获取时间吗?

更新:我正在研究我的便捷方法,并在每个通过获取当前日期和时间开始的方法中使用它:

    LocalDateTime now = LocalDateTime.now();
ZonedDateTime nowLocalTimeZone = ZonedDateTime.of(now, ZoneId.systemDefault());

然后,我使用如下代码获取我真正想要的日期/时间部分:

try {
DateTimeFormatter format = DateTimeFormatter.ofPattern(MONTH_NUMBER_FORMAT);
return Integer.parseInt(nowLocalTimeZone.format(format));
}
catch (DateTimeParseException excp) {
throw excp;
}

请注意,在方法中,一切都基于 LocalDateTime.now() 且未指定时钟。

在我的单元测试中,我将其作为类变量:

    private Clock localClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());

在典型的单元测试中,我有这样的代码:

@Test
@DisplayName ("getCurrentMonthNumberLocal()")
void testGetCurrentMonthNumberLocal() {

LocalDateTime now = LocalDateTime.now(localClock);
ZonedDateTime nowLocalTimeZone = ZonedDateTime.of(now, ZoneId.systemDefault());

//Normal cases
assertEquals(nowLocalTimeZone.getMonthValue(), CurrentDateTimeUtils.getCurrentMonthNumberLocal());
}

请注意,此方法涉及使用名为 localClock 的固定时钟作为预期结果的来源。

当我运行测试时,预期结果与实际结果相匹配(至少对于我到目前为止运行的几个类来说是这样,这些类查找年份和月份编号)。

这种方法是否可以确保我从两个不同的源获取当前时间,以便比较有效?或者我是否有效地从完全相同的来源获取相同的信息,例如计算机上的系统时钟?

我非常希望从方法中获得的日期/时间与用于确定单元测试中的预期结果的日期/时间来自不同的来源,以便我确定这是一个有效的测试,否则,我认为测试这些方法没有多大意义。 (我想我可以只显示每个函数的结果,看看它是否大致正确。很容易判断年、月、日是否正确,除非您可能非常接近该年、月或日的末尾日,在这种情况下,您可能实际上看到了不同时区的值,但并不知道。)

最佳答案

在您的测试中(并且仅在测试期间!)设置您的便利类(class)使用的时钟,以便您可以独立于计算机时钟来预测所需/预期的结果:

public class ConvenienceTest {

@Test
public void testGetLocalHour() {
Convenience underTest = new Convenience();

ZoneId zone = ZoneId.of("America/Los_Angeles");

ZonedDateTime fixedZdt = ZonedDateTime.now(zone).withHour(0);
underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
assertEquals("24", underTest.getLocalHour24HourClock());

fixedZdt = fixedZdt.withHour(1);
underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
assertEquals("01", underTest.getLocalHour24HourClock());

fixedZdt = fixedZdt.withHour(23);
underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
assertEquals("23", underTest.getLocalHour24HourClock());

// TODO test with other time zones
}

}

要实现此功能,当然需要您的便利类可以接受 Clock 并使用它:

public class Convenience {

private Clock clock = Clock.systemDefaultZone();

/** For testing only. Sets the clock from which to get the time. */
void setClock(Clock clockForTest) {
this.clock = clockForTest;
}

public String getLocalHour24HourClock() {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("kk");
ZonedDateTime zdt = ZonedDateTime.now(clock);
return zdt.format(fmt);
}

}

通过此实现,测试刚刚在我的计算机上通过。

退后一步:如果您的便捷方法只是 java.time 之上的一个薄层,您可能会开始考虑单元测试有多少值(value)。如果它正在执行一些实际工作(例如上面示例中的格式化,经常出错的事情),则测试很有值(value),但如果方法仅从对 java.time 的单次调用返回一个值,则可能不需要测试。您不应该测试 java.time,最好只测试您自己的代码。

关于java - 使用 Java 8 Date/Time 类编写和测试便捷方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52956373/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com