@Test public void testLongRunningTaskWithCallback() throws Exception { assertTimeout(ofMillis(5000), () -> { final ThreadAsyncExecutor executor = new ThreadAsyncExecutor(); final Object result = new Object(); final Callable<Object> task = mock(Callable.class); when(task.call()).thenAnswer(i -> { Thread.sleep(1500); return result; }); final AsyncCallback<Object> callback = mock(AsyncCallback.class); final AsyncResult<Object> asyncResult = executor.startProcess(task, callback); assertNotNull(asyncResult); assertFalse(asyncResult.isCompleted()); verifyZeroInteractions(callback); try { asyncResult.getValue(); fail("Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task"); } catch (IllegalStateException e) { assertNotNull(e.getMessage()); } verify(task, timeout(3000).times(1)).call(); final ArgumentCaptor<Optional<Exception>> optionalCaptor = ArgumentCaptor.forClass((Class) Optional.class); verify(callback, timeout(3000).times(1)).onComplete(eq(result), optionalCaptor.capture()); final Optional<Exception> optionalException = optionalCaptor.getValue(); assertNotNull(optionalException); assertFalse(optionalException.isPresent()); asyncResult.await(); assertTrue(asyncResult.isCompleted()); verifyNoMoreInteractions(task, callback); assertSame(result, asyncResult.getValue()); }); }
@Override public <T> AsyncResult<T> startProcess(Callable<T> task) { return startProcess(task, null); }
ThreadAsyncExecutor implements AsyncExecutor { @Override public <T> AsyncResult<T> startProcess(Callable<T> task) { return startProcess(task, null); } }
ThreadAsyncExecutor implements AsyncExecutor { @Override public <T> AsyncResult<T> startProcess(Callable<T> task) { return startProcess(task, null); }  }
ThreadAsyncExecutor implements AsyncExecutor { @Override public <T> AsyncResult<T> startProcess(Callable<T> task) { return startProcess(task, null); }  @Override AsyncResult<T> startProcess(Callable<T> task); @Override AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback); @Override T endProcess(AsyncResult<T> asyncResult); }
ThreadAsyncExecutor implements AsyncExecutor { @Override public <T> AsyncResult<T> startProcess(Callable<T> task) { return startProcess(task, null); }  @Override AsyncResult<T> startProcess(Callable<T> task); @Override AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback); @Override T endProcess(AsyncResult<T> asyncResult);  }