### Question:
CachingAuthenticator implements Authenticator<C, P> { @Override public Optional<P> authenticate(C credentials) throws AuthenticationException { final Timer.Context context = gets.time(); try { Optional<P> optionalPrincipal = cache.getIfPresent(credentials); if (optionalPrincipal == null) { cacheMisses.mark(); optionalPrincipal = underlying.authenticate(credentials); if (optionalPrincipal.isPresent()) { cache.put(credentials, optionalPrincipal); } } return optionalPrincipal; } finally { context.stop(); } } CachingAuthenticator(final MetricRegistry metricRegistry,
                                final Authenticator<C, P> authenticator,
                                final CacheBuilderSpec cacheSpec);  CachingAuthenticator(final MetricRegistry metricRegistry,
                                final Authenticator<C, P> authenticator,
                                final CacheBuilder<Object, Object> builder); @Override Optional<P> authenticate(C credentials); void invalidate(C credentials); void invalidateAll(Iterable<C> credentials); void invalidateAll(Predicate<? super C> predicate); void invalidateAll(); long size(); CacheStats stats();  }### Answer:
@Test public void cachesTheFirstReturnedPrincipal() throws Exception { assertThat(cached.authenticate("credentials")).isEqualTo(Optional.<Principal>of(new PrincipalImpl("principal"))); assertThat(cached.authenticate("credentials")).isEqualTo(Optional.<Principal>of(new PrincipalImpl("principal"))); verify(underlying, times(1)).authenticate("credentials"); }
@Test public void respectsTheCacheConfiguration() throws Exception { cached.authenticate("credentials1"); cached.authenticate("credentials2"); cached.authenticate("credentials1"); final InOrder inOrder = inOrder(underlying); inOrder.verify(underlying, times(1)).authenticate("credentials1"); inOrder.verify(underlying, times(1)).authenticate("credentials2"); inOrder.verify(underlying, times(1)).authenticate("credentials1"); }