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));
}
}