### Question:
KPIAsyncTimer { @Around("cougarAsyncMethod(event, observer)") public Object measureAsyncMethod(final ProceedingJoinPoint pjp, KPIAsyncTimedEvent event, ExecutionObserver observer) throws Throwable { final String eventValue = event.value(); final String eventOperation = event.operation(); final String name = eventValue.isEmpty() ? pjp.getTarget().getClass().getSimpleName() : eventValue; final String operation = eventOperation.isEmpty() ? pjp.getSignature().getName() : eventOperation; final KPITimer timer = new KPITimer(); timer.start(); final PerformanceMonitoringExecutionObserver perfObserver = new PerformanceMonitoringExecutionObserver(observer, monitor, timer, event.catchFailures(), name, operation); return pjp.proceed(replaceObserver(perfObserver, pjp.getArgs())); }  @Around("cougarAsyncMethod(event, observer)") Object measureAsyncMethod(final ProceedingJoinPoint pjp, KPIAsyncTimedEvent event, ExecutionObserver observer); void setMonitor(KPIMonitor monitor);  }### Answer:
@Test public void shouldCallProceedWithWrappedObserver() throws Throwable { when(mockJP.getArgs()).thenReturn(new Object[]{"arg1", "arg2", mockObserver}); timer.measureAsyncMethod(mockJP, mockEvent, mockObserver); verify(mockJP).proceed(argCaptor.capture()); assertTrue(argCaptor.getValue()[2] instanceof PerformanceMonitoringExecutionObserver); ExecutionObserver obs = (ExecutionObserver) argCaptor.getValue()[2]; obs.onResult(mockResult); verify(mockMonitor).addEvent(eq("my.metric"), eq("myOperation"), anyDouble()); }
@Test public void observerNotLastInArgList() throws Throwable { when(mockJP.getArgs()).thenReturn(new Object[]{"arg1", mockObserver, "arg3"}); timer.measureAsyncMethod(mockJP, mockEvent, mockObserver); verify(mockJP).proceed(argCaptor.capture()); assertFalse(argCaptor.getValue()[1] instanceof PerformanceMonitoringExecutionObserver); }
@Test public void multipleObserverArgs() throws Throwable { when(mockJP.getArgs()).thenReturn(new Object[]{"arg1", mockObserver, mockObserver}); timer.measureAsyncMethod(mockJP, mockEvent, mockObserver); verify(mockJP).proceed(argCaptor.capture()); assertFalse(argCaptor.getValue()[1] instanceof PerformanceMonitoringExecutionObserver); assertTrue(argCaptor.getValue()[2] instanceof PerformanceMonitoringExecutionObserver); ExecutionObserver obs = (ExecutionObserver) argCaptor.getValue()[2]; obs.onResult(mockResult); verify(mockMonitor).addEvent(eq("my.metric"), eq("myOperation"), anyDouble()); }