@Override
  public T computeIfAbsent(String key, Function<String, T> supplier) {
    return cache.compute(
        key,
        (String k, T current) -> {
          if (isValidLongEnough(current)) {
            return current;
          }
          return supplier.apply(key);
        });
  }
@Test
  void expires() {
    var clock = new MockClock();
    var ttl = Duration.ofSeconds(10);

    var sut = new InMemoryCacheImpl<CacheEntry>(clock, ttl);

    var now = Instant.parse("2024-01-01T13:11:00.000Z");
    clock.set(now);

    // do NOT use lambda, Mockito can not handle it
    var source =
        spy(
            new Function<String, CacheEntry>() {
              @Override
              public CacheEntry apply(String k) {
                return CacheEntry.of(k, clock.instant().plusSeconds(20));
              }
            });

    var key = "1";

    var N = 10;

    // when
    for (int i = 0; i < N; i++) {
      var r = sut.computeIfAbsent(key, source);
      assertEquals(key, r.value());

      clock.advanceSeconds(30);
    }

    // then
    verify(source, times(N)).apply(key);
  }