### Question:
RetryingMessageReader implements MessageReader { @Override @Retryable(value = { AmazonClientException.class }, maxAttempts = MAX_ATTEMPTS, backoff = @Backoff(delay = INITIAL_DELAY_MS, multiplier = BACKOFF_MULTIPLIER)) public Optional<MessageEvent> read() { return delegate.read(); } RetryingMessageReader(MessageReader delegate); @Override @Retryable(value = { AmazonClientException.class }, maxAttempts = MAX_ATTEMPTS, backoff = @Backoff(delay = INITIAL_DELAY_MS, multiplier = BACKOFF_MULTIPLIER)) Optional<MessageEvent> read(); @Override @Retryable(include = { AmazonClientException.class }, maxAttempts = MAX_ATTEMPTS, backoff = @Backoff(delay = INITIAL_DELAY_MS, multiplier = BACKOFF_MULTIPLIER)) void delete(MessageEvent messageEvent); @Override void close(); @Recover Optional<MessageEvent> recoverRead(AmazonClientException e); @Recover void recoverDelete(AmazonClientException e, MessageEvent messageEvent);  }### Answer:
@Test public void typicalRead() { when(delegate.read()).thenReturn(Optional.of(event)); Optional<MessageEvent> read = retryingMessageReader.read(); assertThat(read).isPresent(); assertThat(read.get()).isEqualTo(event); verify(delegate).read(); }
@Test public void retryRead() { when(delegate.read()).thenThrow(new AmazonClientException("Exception")) .thenReturn(Optional.of(event)); Optional<MessageEvent> read = retryingMessageReader.read(); assertThat(read).isPresent(); assertThat(read.get()).isEqualTo(event); verify(delegate, times(2)).read(); }
@Test public void retryMaxAttemptsRead() { when(delegate.read()).thenThrow(new AmazonClientException("Exception")); assertThatThrownBy(retryingMessageReader::read).isInstanceOf(BeekeeperException.class) .hasMessageContaining("Error reading from queue after " + MAX_ATTEMPTS + " attempts."); verify(delegate, times(MAX_ATTEMPTS)).read(); }