### Question:
ScheduledExecutorAsyncRunner implements AsyncRunner { @Override public <U> SafeFuture<U> runAsync(final Supplier<SafeFuture<U>> action) { if (shutdown.get()) { LOG.debug("Ignoring async task because shutdown is in progress"); return new SafeFuture<>(); } final SafeFuture<U> result = new SafeFuture<>(); try { workerPool.execute(createRunnableForAction(action, result)); } catch (final Throwable t) { handleExecutorError(result, t); } return result; } ScheduledExecutorAsyncRunner(
      final ScheduledExecutorService scheduler, final ExecutorService workerPool); static AsyncRunner create(
      final String name,
      final int maxThreads,
      final MetricTrackingExecutorFactory executorFactory); @Override SafeFuture<U> runAsync(final Supplier<SafeFuture<U>> action); @Override @SuppressWarnings("FutureReturnValueIgnored") SafeFuture<U> runAfterDelay(
      final Supplier<SafeFuture<U>> action, final long delayAmount, final TimeUnit delayUnit); @Override void shutdown();  }### Answer:
@SuppressWarnings("unchecked") @Test public void runAsync_shouldExecuteActionWithExecutorAndReturnResult() { final SafeFuture<String> actionResult = new SafeFuture<>(); final Supplier<SafeFuture<String>> action = mock(Supplier.class); when(action.get()).thenReturn(actionResult); final SafeFuture<String> result = asyncRunner.runAsync(action); verify(action).get(); assertThat(result).isNotDone(); actionResult.complete("Yay"); assertThat(result).isCompletedWithValue("Yay"); }
@SuppressWarnings("unchecked") @Test public void runAsync_shouldExecuteActionWithExecutorAndReturnExceptionalResult() { final SafeFuture<String> actionResult = new SafeFuture<>(); final Supplier<SafeFuture<String>> action = mock(Supplier.class); when(action.get()).thenReturn(actionResult); final SafeFuture<String> result = asyncRunner.runAsync(action); verify(action).get(); assertThat(result).isNotDone(); final RuntimeException exception = new RuntimeException("Nope"); actionResult.completeExceptionally(exception); assertThatSafeFuture(result).isCompletedExceptionallyWith(exception); }
@SuppressWarnings("unchecked") @Test public void runAsync_shouldCompleteExceptionallyWhenExecutorFails() { final Supplier<SafeFuture<String>> action = mock(Supplier.class); final RuntimeException exception = new RuntimeException("Nope"); doThrow(exception).when(workerPool).execute(any()); final SafeFuture<String> result = asyncRunner.runAsync(action); verify(action, never()).get(); assertThatSafeFuture(result).isCompletedExceptionallyWith(exception); }
@Test void runAsyc_shouldCompleteExceptionallyWhenSupplierThrowsException() { final RuntimeException exception = new RuntimeException("My bad..."); final Supplier<SafeFuture<String>> action = () -> { throw exception; }; final SafeFuture<String> result = asyncRunner.runAsync(action); assertThatSafeFuture(result).isCompletedExceptionallyWith(exception); }