ConnectionInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { checkNotNull(method); Optional<String> sql; if ((method.getName().equals("prepareCall") || method.getName().equals("prepareStatement")) && method.getParameterTypes().length > 0 && method.getParameterTypes()[0] == String.class) { sql = Optional.fromNullable((String) args[0]); } else { sql = Optional.absent(); } Object o; try { o = method.invoke(conn, args); } catch (InvocationTargetException e) { throw e.getCause(); } if (o instanceof Statement) { Statement stmt = (Statement) o; o = Proxies.newProxyInstance( stmt, new StatementInvocationHandler(stmt, traceOptions, traceService, sql)); } return o; } ConnectionInvocationHandler(
      Connection conn, TraceOptions traceOptions, TraceService traceService); @Override Object invoke(Object proxy, Method method, Object[] args);  }
@Test public void invoke_close() throws Throwable { connectionInvocationHandler.invoke( mockProxy, Connection.class.getDeclaredMethod("close"), new Object[0]); verify(mockRealConnection).close(); }
@Test public void invoke_commit_fails() throws Throwable { Exception expectedException = new SQLException(); doThrow(expectedException).when(mockRealConnection).commit(); try { connectionInvocationHandler.invoke( mockProxy, Connection.class.getDeclaredMethod("commit"), new Object[0]); fail("expected SQLException"); } catch (Exception actualException) { assertThat(actualException).isSameAs(expectedException); } verify(mockRealConnection).commit(); }
@Test public void invoke_createStatement() throws Throwable { when(mockRealConnection.createStatement()).thenReturn(mockRealStatement); Object o = connectionInvocationHandler.invoke( mockProxy, Connection.class.getDeclaredMethod("createStatement"), new Object[0]); verify(mockRealConnection).createStatement(); assertThat(o instanceof Statement).isTrue(); ((Statement) o).execute("some sql text"); verify(mockRealStatement).execute("some sql text"); }