package net.ttddyy.dsproxy.proxy; import net.ttddyy.dsproxy.listener.QueryExecutionListener; import net.ttddyy.dsproxy.proxy.jdk.JdkJdbcProxyFactory; import net.ttddyy.dsproxy.proxy.jdk.PreparedStatementInvocationHandler; import net.ttddyy.dsproxy.proxy.jdk.StatementInvocationHandler; import net.ttddyy.dsproxy.transform.QueryTransformer; import org.junit.Test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; /** * @author Tadaya Tsuyukubo */ public class ConnectionProxyLogicMockTest { @Test public void testCreateStatementWithNoParam() throws Throwable { Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); Method method = Connection.class.getMethod("createStatement"); Object result = logic.invoke(method, new Object[]{}); assertThat(result, is(instanceOf(Statement.class))); verifyStatement((Statement) result); verify(conn).createStatement(); } @Test public void testCreateStatementWithTwoParam() throws Throwable { Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); Method method = Connection.class.getMethod("createStatement", int.class, int.class); Object result = logic.invoke(method, new Object[]{ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY}); assertThat(result, is(instanceOf(Statement.class))); verifyStatement((Statement) result); verify(conn).createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } @Test public void testCreateStatementWithThreeParam() throws Throwable { // expect Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); // run Method method = Connection.class.getMethod("createStatement", int.class, int.class, int.class); Object result = logic.invoke(method, new Object[]{ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT}); // verify assertThat(result, is(instanceOf(Statement.class))); verifyStatement((Statement) result); verify(conn).createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); } private ConnectionProxyLogic getProxyLogic(Connection mockConnection) { QueryExecutionListener listener = mock(QueryExecutionListener.class); InterceptorHolder interceptorHolder = new InterceptorHolder(listener, QueryTransformer.DEFAULT); return new ConnectionProxyLogic(mockConnection, interceptorHolder, "myDS", new JdkJdbcProxyFactory()); } private void verifyStatement(Statement statement) { assertThat(statement, notNullValue()); assertThat(Proxy.isProxyClass(statement.getClass()), is(true)); InvocationHandler handler = Proxy.getInvocationHandler(statement); assertThat(handler, is(instanceOf(StatementInvocationHandler.class))); } @Test public void testPrepareStatement() throws Throwable { // expect Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); String query = "select * from emp"; // run Method method = Connection.class.getMethod("prepareStatement", String.class); Object result = logic.invoke(method, new Object[]{query}); // verify assertThat(result, is(instanceOf(PreparedStatement.class))); verifyPreparedStatement((PreparedStatement) result); } @Test public void testPrepareStatementWithAutoGeneratedKeys() throws Throwable { // expect Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); String query = "select * from emp"; // run Method method = Connection.class.getMethod("prepareStatement", String.class, int.class); Object result = logic.invoke(method, new Object[]{query, Statement.RETURN_GENERATED_KEYS}); // verify assertThat(result, is(instanceOf(PreparedStatement.class))); verifyPreparedStatement((PreparedStatement) result); verify(conn).prepareStatement(query, Statement.RETURN_GENERATED_KEYS); } @Test public void testPrepareStatementWithColumnIndexes() throws Throwable { // expect Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); String query = "select * from emp"; int[] columnIndexes = new int[]{1, 2, 3}; // run Method method = Connection.class.getMethod("prepareStatement", String.class, int[].class); Object result = logic.invoke(method, new Object[]{query, columnIndexes}); // verify assertThat(result, is(instanceOf(PreparedStatement.class))); verifyPreparedStatement((PreparedStatement) result); verify(conn).prepareStatement(query, columnIndexes); } @Test public void testPrepareStatementWithColumnNames() throws Throwable { // expect Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); String query = "select * from emp"; String[] columnNames = new String[]{"id", "name"}; // run Method method = Connection.class.getMethod("prepareStatement", String.class, String[].class); Object result = logic.invoke(method, new Object[]{query, columnNames}); // verify assertThat(result, is(instanceOf(PreparedStatement.class))); verifyPreparedStatement((PreparedStatement) result); verify(conn).prepareStatement(query, columnNames); } @Test public void testPrepareStatementWithTwoResultSetParams() throws Throwable { // expect Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); String query = "select * from emp"; // run Method method = Connection.class.getMethod("prepareStatement", String.class, int.class, int.class); Object result = logic.invoke(method, new Object[]{query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY}); // verify assertThat(result, is(instanceOf(PreparedStatement.class))); verifyPreparedStatement((PreparedStatement) result); verify(conn).prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } @Test public void testPrepareStatementWithThreeResultSetParams() throws Throwable { // expect Connection conn = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(conn); String query = "select * from emp"; // run Method method = Connection.class.getMethod("prepareStatement", String.class, int.class, int.class, int.class); Object result = logic.invoke(method, new Object[]{query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT}); // verify assertThat(result, is(instanceOf(PreparedStatement.class))); verifyPreparedStatement((PreparedStatement) result); verify(conn).prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); } private void verifyPreparedStatement(PreparedStatement statement) { assertThat(statement, notNullValue()); assertThat(Proxy.isProxyClass(statement.getClass()), is(true)); InvocationHandler handler = Proxy.getInvocationHandler(statement); assertThat(handler, is(instanceOf(PreparedStatementInvocationHandler.class))); } @Test public void testGetTarget() throws Throwable { Connection orig = mock(Connection.class); ConnectionProxyLogic logic = getProxyLogic(orig); // run Method method = ProxyJdbcObject.class.getMethod("getTarget"); Object result = logic.invoke(method, null); assertThat(result, is(instanceOf(Connection.class))); Connection resultConn = (Connection) result; assertThat(resultConn, is(sameInstance(orig))); } @Test public void testUnwrap() throws Throwable { Connection mock = mock(Connection.class); when(mock.unwrap(String.class)).thenReturn("called"); ConnectionProxyLogic logic = getProxyLogic(mock); // run Method method = Connection.class.getMethod("unwrap", Class.class); Object result = logic.invoke(method, new Object[]{String.class}); verify(mock).unwrap(String.class); assertThat(result, is(instanceOf(String.class))); assertThat((String) result, is("called")); } @Test public void testIsWrapperFor() throws Throwable { Connection mock = mock(Connection.class); when(mock.isWrapperFor(String.class)).thenReturn(true); ConnectionProxyLogic logic = getProxyLogic(mock); // run Method method = Connection.class.getMethod("isWrapperFor", Class.class); Object result = logic.invoke(method, new Object[]{String.class}); verify(mock).isWrapperFor(String.class); assertThat(result, is(instanceOf(boolean.class))); assertThat((Boolean) result, is(true)); } }