### Question:
FallbackPolicy { public SagaResponse apply(String address, Compensation compensation, Fallback fallback) { for (int i = 0; isRetryable(i, compensation) && !isInterrupted(); i++) { try { return compensation.send(address); } catch (Exception e) { log.error("Failed to send compensation to {}", address, e); sleep(retryDelay); } } log.warn("Falling back after {} failures sending compensation to {}", compensation.retries(), address); return fallback.send(address); } FallbackPolicy(int retryDelay); SagaResponse apply(String address, Compensation compensation, Fallback fallback);  }### Answer:
@Test public void retriesTransportForSpecifiedTimes() { when(compensation.send(address)) .thenThrow(exception) .thenThrow(exception) .thenReturn(success); SagaResponse response = fallbackPolicy.apply(address, compensation, fallback); assertThat(response, is(success)); verify(compensation, times(3)).send(address); }
@Test public void fallbackIfTransportFailedWithRetry() { when(compensation.send(address)).thenThrow(exception); SagaResponse response = fallbackPolicy.apply(address, compensation, fallback); assertThat(response, is(failure)); verify(compensation, times(numberOfRetries + 1)).send(address); verify(fallback).send(address); }
@Test public void retryUntilSuccessIfNumberOfRetriesIsNegative() throws InterruptedException { reset(compensation); when(compensation.retries()).thenReturn(-1); when(compensation.send(address)) .thenThrow(exception, exception, exception, exception, exception) .thenReturn(success); SagaResponse response = fallbackPolicy.apply(address, compensation, fallback); assertThat(response, is(success)); verify(fallback, never()).send(anyString()); }