package com.aconex.scrutineer.jdbc;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.aconex.scrutineer.IdAndVersionFactory;
import com.aconex.scrutineer.StringIdAndVersion;
public class JdbcIdAndVersionStreamTest {
private static final String SQL = "select id, version from tablename order by id";
private IdAndVersionFactory idAndVersionFactory = StringIdAndVersion.FACTORY;
@Mock
private Connection connection;
@Mock
private Statement statement;
@Mock
private ResultSet resultSet;
@Mock
private ResultSetMetaData metaData;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldCloseDBResourcesEvenIfNoIteration() throws SQLException {
when(connection.createStatement()).thenReturn(statement);
when(statement.executeQuery(SQL)).thenReturn(resultSet);
when(resultSet.getMetaData()).thenReturn(metaData);
JdbcIdAndVersionStream jdbcIdAndVersionStream = new JdbcIdAndVersionStream(connection, SQL, idAndVersionFactory);
jdbcIdAndVersionStream.open();
jdbcIdAndVersionStream.close();
verify(statement).close();
verify(resultSet).close();
verify(connection, never()).close();
}
@Test
public void closeShouldDoNothingIfNotOpen() throws SQLException {
JdbcIdAndVersionStream jdbcIdAndVersionStream = new JdbcIdAndVersionStream(connection, SQL, idAndVersionFactory);
jdbcIdAndVersionStream.close();
verifyNoMoreInteractions(connection);
}
@Test
public void shouldExecuteSQLQuery() throws SQLException {
when(connection.createStatement()).thenReturn(statement);
//TODO: Handle scrolling properly
when(statement.executeQuery(SQL)).thenReturn(resultSet);
when(resultSet.getMetaData()).thenReturn(metaData);
JdbcIdAndVersionStream jdbcIdAndVersionStream = new JdbcIdAndVersionStream(connection, SQL, idAndVersionFactory);
jdbcIdAndVersionStream.open();
IdAndVersionResultSetIterator iterator = (IdAndVersionResultSetIterator) jdbcIdAndVersionStream.iterator();
assertThat(iterator.getResultSet(), is(resultSet));
verify(statement).executeQuery(SQL);
}
@Test
public void shouldTearDownStatement() throws SQLException {
when(connection.createStatement()).thenReturn(statement);
when(statement.executeQuery(SQL)).thenReturn(resultSet);
when(resultSet.getMetaData()).thenReturn(metaData);
JdbcIdAndVersionStream jdbcIdAndVersionStream = new JdbcIdAndVersionStream(connection, SQL, idAndVersionFactory);
jdbcIdAndVersionStream.open();
jdbcIdAndVersionStream.iterator();
jdbcIdAndVersionStream.close();
verify(resultSet).close();
verify(statement).close();
}
@Test(expected = RuntimeException.class)
public void shouldThrowExceptionIfResultSetFailsToClose() throws SQLException {
try {
when(connection.createStatement()).thenReturn(statement);
when(statement.executeQuery(SQL)).thenReturn(resultSet);
} catch (SQLException e) {
e.printStackTrace();
fail("Unexpected exception");
}
doThrow(new SQLException()).when(resultSet).close();
JdbcIdAndVersionStream jdbcIdAndVersionStream = new JdbcIdAndVersionStream(connection, SQL, idAndVersionFactory);
jdbcIdAndVersionStream.open();
jdbcIdAndVersionStream.iterator();
jdbcIdAndVersionStream.close();
}
}