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

How to mock current date time for passing a quality gate pass in java

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

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"))" 时它将使用模拟的 dateTime?

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

例如

public interface TimeProvider {
    ZonedDateTime getCurrentZonedDateTime()
}

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

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

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

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