### Question:
TracingCommandGateway implements CommandGateway { @Override public <C, R> void send(C command, CommandCallback<? super C, ? super R> callback) { CommandMessage<? super C> cmd = GenericCommandMessage.asCommandMessage(command); sendWithSpan("send_" + SpanUtils.messageName(cmd), cmd, (childSpan) -> { CompletableFuture<?> resultReceived = new CompletableFuture<>(); delegate.send(cmd, (CommandCallback<Object, R>) (commandMessage, commandResultMessage) -> { try (Scope ignored = tracer.activateSpan(childSpan)) { childSpan.log("resultReceived"); callback.onResult((CommandMessage<? extends C>) commandMessage, commandResultMessage); childSpan.log("afterCallbackInvocation"); } finally { resultReceived.complete(null); } }); childSpan.log("dispatchComplete"); resultReceived.thenRun(childSpan::finish); }); } protected  TracingCommandGateway(Builder builder); static Builder builder(); @Override void send(C command, CommandCallback<? super C, ? super R> callback); @Override R sendAndWait(Object command); @Override R sendAndWait(Object command, long timeout, TimeUnit unit); @Override CompletableFuture<R> send(Object command); @Override Registration registerDispatchInterceptor(
            MessageDispatchInterceptor<? super CommandMessage<?>> dispatchInterceptor);  }### Answer:
@Test void testSendWithCallback() { MockSpan span = mockTracer.buildSpan("test").start(); ScopeManager scopeManager = mockTracer.scopeManager(); try (final Scope ignored = scopeManager.activate(span)) { testSubject.send(new MyCommand(), (m, r) -> { assertNotNull(r); }); verify(mockCommandBus, times(1)) .dispatch(isA(CommandMessage.class), isA(CommandCallback.class)); Span activeSpan = mockTracer.activeSpan(); assertEquals(span, activeSpan); List<MockSpan> mockSpans = mockTracer.finishedSpans(); assertEquals(1, mockSpans.size()); assertEquals("send_MyCommand", mockSpans.get(0).operationName()); assertNotNull(mockSpans.get(0).logEntries()); assertFalse(mockSpans.get(0).logEntries().isEmpty()); assertNotNull(mockSpans.get(0).tags()); assertFalse(mockSpans.get(0).tags().isEmpty()); } assertNull(scopeManager.activeSpan(), "There should be no activeSpan"); }
@Test void testSendWithoutCallback() throws ExecutionException, InterruptedException { MockSpan span = mockTracer.buildSpan("test").start(); ScopeManager scopeManager = mockTracer.scopeManager(); try (final Scope ignored = scopeManager.activate(span)) { CompletableFuture<Object> future = testSubject.send(new MyCommand()); verify(mockCommandBus, times(1)) .dispatch(isA(CommandMessage.class), isA(CommandCallback.class)); assertTrue(future.isDone()); assertEquals("result", future.get()); Span activeSpan = mockTracer.activeSpan(); assertEquals(span, activeSpan); List<MockSpan> mockSpans = mockTracer.finishedSpans(); assertEquals(1, mockSpans.size()); assertEquals("send_MyCommand", mockSpans.get(0).operationName()); assertNotNull(mockSpans.get(0).logEntries()); assertFalse(mockSpans.get(0).logEntries().isEmpty()); assertNotNull(mockSpans.get(0).tags()); assertFalse(mockSpans.get(0).tags().isEmpty()); } assertNull(scopeManager.activeSpan(), "There should be no activeSpan"); }