HttpTimestampSupplier { @VisibleForTesting String currentTimestamp() { final long currentTimeNanos = nanoTimeSupplier.getAsLong(); if (nextUpdateNanos - currentTimeNanos > 0) { return timestamp; } final Instant now = instantSupplier.get(); nextUpdateNanos = currentTimeNanos - now.getNano() + NANOS_IN_SECOND; return timestamp = DateTimeFormatter.RFC_1123_DATE_TIME.format( ZonedDateTime.ofInstant(now, ZoneOffset.UTC)); } private  HttpTimestampSupplier(); @VisibleForTesting  HttpTimestampSupplier(Supplier<Instant> instantSupplier, LongSupplier nanoTimeSupplier); static String currentTime();  }
@Test void normal() { when(nanoTimeSupplier.getAsLong()).thenReturn(TimeUnit.MILLISECONDS.toNanos(-500)); when(instantSupplier.get()).thenReturn(TIME0); final HttpTimestampSupplier supplier = new HttpTimestampSupplier(instantSupplier, nanoTimeSupplier); verify(instantSupplier, never()).get(); verify(nanoTimeSupplier, times(1)).getAsLong(); clearInvocations(instantSupplier, nanoTimeSupplier); final String timestamp1 = supplier.currentTimestamp(); assertThat(timestamp1).isEqualTo("Fri, 18 Oct 2019 10:15:30 GMT"); verify(instantSupplier, times(1)).get(); verify(nanoTimeSupplier, times(1)).getAsLong(); clearInvocations(instantSupplier, nanoTimeSupplier); when(nanoTimeSupplier.getAsLong()).thenReturn(TimeUnit.MILLISECONDS.toNanos(-500 + 950) - 1); when(instantSupplier.get()).thenReturn(null); final String timestamp2 = supplier.currentTimestamp(); assertThat(timestamp2).isSameAs(timestamp1); verify(instantSupplier, never()).get(); verify(nanoTimeSupplier, times(1)).getAsLong(); clearInvocations(instantSupplier, nanoTimeSupplier); when(nanoTimeSupplier.getAsLong()).thenReturn(TimeUnit.MILLISECONDS.toNanos(-500 + 950)); when(instantSupplier.get()).thenReturn(TIME1); assertThat(supplier.currentTimestamp()).isEqualTo("Fri, 18 Oct 2019 10:15:31 GMT"); }