DoneAnswer implements Answer<S> { @NotNull @Override public Answer<S> whenCompleted(@NotNull Consumer<S> c) { if (error == null) { c.accept(result); } return this; } private  DoneAnswer(S result, P4CommandRunner.ServerResultException error); static Answer<S> resolve(@Nullable S s); static Answer<S> reject(@NotNull P4CommandRunner.ServerResultException error); @NotNull @Override Answer<S> whenCompleted(@NotNull Consumer<S> c); @NotNull @Override Answer<S> whenFailed(@NotNull Consumer<P4CommandRunner.ServerResultException> c); @NotNull @Override Answer<T> map(@NotNull Function<S, T> fun); @NotNull @Override Answer<T> mapAsync(@NotNull Function<S, Answer<T>> fun); @NotNull @Override Answer<T> futureMap(@NotNull BiConsumer<S, AnswerSink<T>> func); @Override boolean blockingWait(int timeout, TimeUnit unit);  }
@Test void whenCompleted() throws InterruptedException { final Object result = new Object(); final Answer<Object> da = DoneAnswer.resolve(result); assertTrue(da.blockingWait(1, TimeUnit.MILLISECONDS)); final AtomicInteger count = new AtomicInteger(0); da.whenCompleted((c) -> { assertSame(result, c); count.incrementAndGet(); }) .whenFailed(Assertions::fail); assertEquals(1, count.get()); }