如何在java中模拟当前日期时间以通过质量门通行证

发布时间:2021-03-08 12:33

我想为当前时间逻辑编写测试用例。这是我的 Java 课程。

public static void main(String []args){
        final ZonedDateTime passedDate = ZonedDateTime.parse("2021-03-09T05:00:00.000Z");
        if(isAgentConfirmationRequired()) {
         // Some codes...
          }
     }
private static boolean isAgentConfirmationRequired(final ZonedDateTime appointment)
    {
        final ZonedDateTime appointmentTime = appointment.withZoneSameInstant(ZoneId.of("Europe/Paris"));
        final ZonedDateTime todayTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
        final DayOfWeek dayOfToday = todayTime.toLocalDate().getDayOfWeek();
        if (dayOfToday == DayOfWeek.SATURDAY || dayOfToday == DayOfWeek.SUNDAY) {
            // For weekend user can't update appointment for next business day.
            return appointmentTime.toLocalDate().isBefore(getNextAvailableBusinessDayForBooking(todayTime));
        }
        return todayTime.toLocalTime().isAfter(LocalTime.of(THREE_PM, 0)) && appointmentTime.toLocalDate().isBefore(getNextAvailableBusinessDayForBooking(todayTime));
    }

private LocalDate getNextAvailableBusinessDayForBooking(final ZonedDateTime today)
    {
        long nextAvailableDayCount = 2;
        final DayOfWeek day = today.toLocalDate().plusDays(nextAvailableDayCount).getDayOfWeek();
        if (day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY) {
            nextAvailableDayCount += 2;
        } else if (day == DayOfWeek.MONDAY) {
            nextAvailableDayCount += 1;
        }
        return today.toLocalDate().plusDays(nextAvailableDayCount);
    }

如果当前时间不在下午 3 点之后,则代码覆盖率低于 50%。有人可以建议我如何在测试用例中模拟 currentDateTime,所以当涉及到“ZonedDateTime.now(ZoneId.of("Europe/Paris"))”时,它将使用模拟的日期时间?

回答1

测试应该在何时何地执行是独立的。为了使它们独立于当前环境时间,您应该考虑创建一个提供当前时间的接口。

例如

public interface TimeProvider {
    ZonedDateTime getCurrentZonedDateTime()
}

对于生产代码,您有一个返回当前时间的简单实现,对于测试,您可以模拟其行为,例如使用 Mockito

var timeProvider = Mockito.mock(TimeProvicer.class)
var testTime = ...
Mockito.when(timeprovider.getCurrentZonedDateTime()).thenReturn( testTime )
myProgram.setTimeProvider(timeProvider)

现在测试将始终返回相同的结果。

也许您需要确保除了默认的 ZonedDateTime.now() 实现之外,您不会调用 TimeProvider(或任何其他返回当前时间的方法)。