AuthenticationChain { public CompletableFuture<AuthenticationResult> authenticate(final RequestContext requestContext, final DittoHeaders dittoHeaders) { return CompletableFuture .runAsync(() -> LogUtil.enhanceLogWithCorrelationId(dittoHeaders), authenticationDispatcher) .thenApply(voidValue -> doAuthenticate(requestContext, dittoHeaders)); } private  AuthenticationChain(final Collection<AuthenticationProvider<?>> authenticationProviders,
            final AuthenticationFailureAggregator authenticationFailureAggregator,
            final Executor authenticationDispatcher); static AuthenticationChain getInstance(final Collection<AuthenticationProvider<?>> authenticationProviders,
            final AuthenticationFailureAggregator authenticationFailureAggregator,
            final Executor authenticationDispatcher); CompletableFuture<AuthenticationResult> authenticate(final RequestContext requestContext,
            final DittoHeaders dittoHeaders);  }
@Test public void authenticate() throws ExecutionException, InterruptedException { final RequestContext requestContextMock = mockRequestContextForAuthenticate(); final AuthenticationResult expectedAuthenticationResult = DefaultAuthenticationResult.successful(dittoHeaders, knownAuthorizationContext); when(authenticationProviderA.isApplicable(requestContextMock)).thenReturn(false); when(authenticationProviderB.isApplicable(requestContextMock)).thenReturn(true); when(authenticationProviderB.authenticate(requestContextMock, dittoHeaders)) .thenReturn(expectedAuthenticationResult); final AuthenticationChain underTest = AuthenticationChain.getInstance(Arrays.asList(authenticationProviderA, authenticationProviderB), authenticationFailureAggregator, messageDispatcher); final AuthenticationResult authenticationResult = underTest.authenticate(requestContextMock, dittoHeaders).get(); verify(authenticationProviderA).isApplicable(requestContextMock); verify(authenticationProviderB).isApplicable(requestContextMock); verify(authenticationProviderA, never()).authenticate(requestContextMock, dittoHeaders); verify(authenticationProviderB).authenticate(requestContextMock, dittoHeaders); softly.assertThat(authenticationResult).isEqualTo(expectedAuthenticationResult); }