src/main/java/net/ttddyy/dsproxy/asserts/PreparedBatchExecution.java
public class PreparedBatchExecution extends BaseQueryExecution implements QueryHolder, BatchParameterHolder, BatchExecution {

    private String query;
    private List<BatchExecutionEntry> batchExecutionEntries = new ArrayList<>();

    @Override
    public boolean isBatch() {
        return true;
    }

    public void setQuery(String query) {
        this.query = query;
    }

    @Override
    public String getQuery() {
        return this.query;
    }

    @Override
    public List<BatchExecutionEntry> getBatchExecutionEntries() {
        return this.batchExecutionEntries;
    }

    public boolean addBatchExecutionEntry(PreparedBatchExecutionEntry entry) {
        return this.batchExecutionEntries.add(entry);
    }

    @SuppressWarnings("unchecked")
    public List<PreparedBatchExecutionEntry> getPrepareds() {

        return (List<PreparedBatchExecutionEntry>) (List<?>) this.batchExecutionEntries;
    }

}
src/main/java/net/ttddyy/dsproxy/asserts/BatchExecutionEntry.java
public interface BatchExecutionEntry {

}
src/main/java/net/ttddyy/dsproxy/asserts/CallableBatchExecutionEntry.java
public class CallableBatchExecutionEntry implements BatchExecutionEntry, ParameterByIndexHolder, ParameterByNameHolder, OutParameterHolder {

    private SortedSet<ParameterKeyValue> parameters = new TreeSet<>();

    @Override
    public SortedSet<ParameterKeyValue> getAllParameters() {
        return this.parameters;
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_PARAM);
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetNullParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_NULL);
    }

    @Override
    public SortedSet<ParameterKeyValue> getOutParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.REGISTER_OUT);
    }

    @Override
    public Map<String, Object> getSetParamsByName() {
        return toKeyNameMap(filterByKeyType(getSetParams(), ParameterKey.ParameterKeyType.BY_NAME));
    }

    @Override
    public Map<Integer, Object> getSetParamsByIndex() {
        return toKeyIndexMap(
                filterByKeyType(getSetParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public Map<String, Integer> getSetNullParamsByName() {
        return toKeyNameMap(
                filterByKeyType(getSetNullParams(), ParameterKey.ParameterKeyType.BY_NAME));
    }

    @Override
    public Map<Integer, Integer> getSetNullParamsByIndex() {
        return toKeyIndexMap(
                filterByKeyType(getSetNullParams(), ParameterKey.ParameterKeyType.BY_INDEX));

    }

    @Override
    public Map<String, Object> getOutParamsByName() {
        return toKeyNameMap(filterByKeyType(getOutParams(), ParameterKey.ParameterKeyType.BY_NAME));
    }

    @Override
    public Map<Integer, Object> getOutParamsByIndex() {
        return toKeyIndexMap(
                filterByKeyType(getOutParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public List<String> getParamNames() {
        List<String> names = new ArrayList<>();
        names.addAll(getSetParamsByName().keySet());
        names.addAll(getSetNullParamsByName().keySet());
        return names;
    }

    @Override
    public List<Integer> getParamIndexes() {
        List<Integer> indexes = new ArrayList<>();
        indexes.addAll(getSetParamsByIndex().keySet());
        indexes.addAll(getSetNullParamsByIndex().keySet());
        return indexes;
    }

    @Override
    public List<String> getOutParamNames() {
        return new ArrayList<>(getOutParamsByName().keySet());
    }

    @Override
    public List<Integer> getOutParamIndexes() {
        return new ArrayList<>(getOutParamsByIndex().keySet());
    }

}
src/main/java/net/ttddyy/dsproxy/asserts/PreparedExecution.java
public class PreparedExecution extends BaseQueryExecution implements QueryHolder, ParameterByIndexHolder {

    private String query;
    private SortedSet<ParameterKeyValue> parameters = new TreeSet<>();

    @Override
    public boolean isBatch() {
        return false;
    }

    @Override
    public String getQuery() {
        return this.query;
    }

    public void setQuery(String query) {
        this.query = query;
    }

    @Override
    public SortedSet<ParameterKeyValue> getAllParameters() {
        return this.parameters;
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_PARAM);
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetNullParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_NULL);
    }

    @Override
    public Map<Integer, Object> getSetParamsByIndex() {
        return toKeyIndexMap(filterByKeyType(getSetParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public Map<Integer, Integer> getSetNullParamsByIndex() {
        return toKeyIndexMap(filterByKeyType(getSetNullParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public List<Integer> getParamIndexes() {
        List<Integer> indexes = new ArrayList<>();
        indexes.addAll(getSetParamsByIndex().keySet());
        indexes.addAll(getSetNullParamsByIndex().keySet());
        return indexes;
    }

}
src/main/java/net/ttddyy/dsproxy/asserts/StatementBatchExecution.java
public class StatementBatchExecution extends BaseQueryExecution implements QueriesHolder, BatchExecution {

    private List<String> queries = new ArrayList<>();

    @Override
    public boolean isBatch() {
        return true;
    }

    @Override
    public List<String> getQueries() {
        return this.queries;
    }

    public void setQueries(List<String> queries) {
        this.queries = queries;
    }

}
src/main/java/net/ttddyy/dsproxy/asserts/StatementExecution.java
public class StatementExecution extends BaseQueryExecution implements QueryHolder {

    private String query;

    @Override
    public boolean isBatch() {
        return false;
    }

    @Override
    public String getQuery() {
        return this.query;
    }

    public void setQuery(String query) {
        this.query = query;
    }

}
src/main/java/net/ttddyy/dsproxy/asserts/QueryExecution.java
public interface QueryExecution {

    boolean isSuccess();

    boolean isBatch();

}
src/main/java/net/ttddyy/dsproxy/asserts/PreparedBatchExecutionEntry.java
public class PreparedBatchExecutionEntry implements BatchExecutionEntry, ParameterByIndexHolder {

    private SortedSet<ParameterKeyValue> parameters = new TreeSet<>();

    @Override
    public SortedSet<ParameterKeyValue> getAllParameters() {
        return this.parameters;
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_PARAM);
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetNullParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_NULL);
    }


    @Override
    public Map<Integer, Object> getSetParamsByIndex() {
        return toKeyIndexMap(filterByKeyType(getSetParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public Map<Integer, Integer> getSetNullParamsByIndex() {
        return toKeyIndexMap(filterByKeyType(getSetNullParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public List<Integer> getParamIndexes() {
        List<Integer> indexes = new ArrayList<>();
        indexes.addAll(getSetParamsByIndex().keySet());
        indexes.addAll(getSetNullParamsByIndex().keySet());
        return indexes;
    }

}
src/main/java/net/ttddyy/dsproxy/asserts/ProxyTestDataSource.java
public class ProxyTestDataSource extends ProxyDataSource {

    private QueryExecutionFactoryListener queryExecutionFactoryListener = new QueryExecutionFactoryListener();


    public ProxyTestDataSource() {
        initialize();
    }

    public ProxyTestDataSource(DataSource dataSource) {
        super(dataSource);
        initialize();
    }

    private void initialize() {
        this.getProxyConfig().getQueryListener().addListener(this.queryExecutionFactoryListener);
    }

    public void reset() {
        this.queryExecutionFactoryListener.reset();
    }

    public List<StatementExecution> getStatements() {
        return getQueryExecutionsFilteredBy(StatementExecution.class);
    }

    public StatementExecution getFirstStatement() {
        return getFirstQueryExecution(StatementExecution.class);
    }

    public StatementExecution getLastStatement() {
        return getLastQueryExecution(StatementExecution.class);
    }

    public List<StatementBatchExecution> getBatchStatements() {
        return getQueryExecutionsFilteredBy(StatementBatchExecution.class);
    }

    public StatementBatchExecution getFirstBatchStatement() {
        return getFirstQueryExecution(StatementBatchExecution.class);
    }

    public StatementBatchExecution getLastBatchStatement() {
        return getLastQueryExecution(StatementBatchExecution.class);
    }

    public List<PreparedExecution> getPrepareds() {
        return getQueryExecutionsFilteredBy(PreparedExecution.class);
    }

    public PreparedExecution getFirstPrepared() {
        return getFirstQueryExecution(PreparedExecution.class);
    }

    public PreparedExecution getLastPrepared() {
        return getLastQueryExecution(PreparedExecution.class);
    }

    public List<PreparedBatchExecution> getBatchPrepareds() {
        return getQueryExecutionsFilteredBy(PreparedBatchExecution.class);
    }

    public PreparedBatchExecution getFirstBatchPrepared() {
        return getFirstQueryExecution(PreparedBatchExecution.class);
    }

    public PreparedBatchExecution getLastBatchPrepared() {
        return getLastQueryExecution(PreparedBatchExecution.class);
    }

    public List<CallableExecution> getCallables() {
        return getQueryExecutionsFilteredBy(CallableExecution.class);
    }

    public CallableExecution getFirstCallable() {
        return getFirstQueryExecution(CallableExecution.class);
    }

    public CallableExecution getLastCallable() {
        return getLastQueryExecution(CallableExecution.class);
    }

    public List<CallableBatchExecution> getBatchCallables() {
        return getQueryExecutionsFilteredBy(CallableBatchExecution.class);
    }

    public CallableBatchExecution getFirstBatchCallable() {
        return getFirstQueryExecution(CallableBatchExecution.class);
    }

    public CallableBatchExecution getLastBatchCallable() {
        return getLastQueryExecution(CallableBatchExecution.class);
    }


    @SuppressWarnings("unchecked")
    private <T extends QueryExecution> List<T> getQueryExecutionsFilteredBy(Class<T> classToFilter) {
        List<T> result = new ArrayList<>();
        for (QueryExecution queryExecution : getQueryExecutions()) {
            if (classToFilter.isAssignableFrom(queryExecution.getClass())) {
                result.add((T) queryExecution);
            }
        }
        return result;
    }

    private <T extends QueryExecution> T getFirstQueryExecution(Class<T> classToFilter) {
        List<T> filtered = getQueryExecutionsFilteredBy(classToFilter);
        if (filtered.isEmpty()) {
            return null;
        }
        return filtered.get(0);
    }

    private <T extends QueryExecution> T getLastQueryExecution(Class<T> classToFilter) {
        List<T> filtered = getQueryExecutionsFilteredBy(classToFilter);
        if (filtered.isEmpty()) {
            return null;
        }
        return filtered.get(filtered.size() - 1);
    }

    public List<QueryExecution> getQueryExecutions() {
        return this.queryExecutionFactoryListener.getQueryExecutions();
    }

    public QueryExecutionFactoryListener getQueryExecutionFactoryListener() {
        return this.queryExecutionFactoryListener;
    }
}
src/main/java/net/ttddyy/dsproxy/asserts/CallableBatchExecution.java
public class CallableBatchExecution extends BaseQueryExecution implements BatchParameterHolder, QueryHolder, BatchExecution {

    private String query;

    private List<BatchExecutionEntry> batchExecutionEntries = new ArrayList<>();

    @Override
    public boolean isBatch() {
        return true;
    }

    public void setQuery(String query) {
        this.query = query;
    }

    @Override
    public String getQuery() {
        return this.query;
    }

    @Override
    public List<BatchExecutionEntry> getBatchExecutionEntries() {
        return this.batchExecutionEntries;
    }

    public boolean addBatchExecutionEntry(CallableBatchExecutionEntry entry) {
        return this.batchExecutionEntries.add(entry);
    }

}
src/main/java/net/ttddyy/dsproxy/asserts/CallableExecution.java
public class CallableExecution extends BaseQueryExecution implements QueryHolder, ParameterByIndexHolder, ParameterByNameHolder, OutParameterHolder {

    private String query;
    private SortedSet<ParameterKeyValue> parameters = new TreeSet<>();


    @Override
    public boolean isBatch() {
        return false;
    }

    @Override
    public String getQuery() {
        return this.query;
    }

    public void setQuery(String query) {
        this.query = query;
    }

    @Override
    public SortedSet<ParameterKeyValue> getAllParameters() {
        return this.parameters;
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_PARAM);
    }

    @Override
    public SortedSet<ParameterKeyValue> getSetNullParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.SET_NULL);
    }

    @Override
    public SortedSet<ParameterKeyValue> getOutParams() {
        return filterBy(this.parameters, ParameterKeyValue.OperationType.REGISTER_OUT);
    }

    @Override
    public Map<String, Object> getSetParamsByName() {
        return toKeyNameMap(filterByKeyType(getSetParams(), ParameterKey.ParameterKeyType.BY_NAME));
    }

    @Override
    public Map<Integer, Object> getSetParamsByIndex() {
        return toKeyIndexMap(filterByKeyType(getSetParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public Map<String, Integer> getSetNullParamsByName() {
        return toKeyNameMap(filterByKeyType(getSetNullParams(), ParameterKey.ParameterKeyType.BY_NAME));
    }

    @Override
    public Map<Integer, Integer> getSetNullParamsByIndex() {
        return toKeyIndexMap(filterByKeyType(getSetNullParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public Map<String, Object> getOutParamsByName() {
        return toKeyNameMap(filterByKeyType(getOutParams(), ParameterKey.ParameterKeyType.BY_NAME));
    }

    @Override
    public Map<Integer, Object> getOutParamsByIndex() {
        return toKeyIndexMap(filterByKeyType(getOutParams(), ParameterKey.ParameterKeyType.BY_INDEX));
    }

    @Override
    public List<String> getParamNames() {
        List<String> names = new ArrayList<>();
        names.addAll(getSetParamsByName().keySet());
        names.addAll(getSetNullParamsByName().keySet());
        return names;
    }

    @Override
    public List<Integer> getParamIndexes() {
        List<Integer> indexes = new ArrayList<>();
        indexes.addAll(getSetParamsByIndex().keySet());
        indexes.addAll(getSetNullParamsByIndex().keySet());
        return indexes;
    }

    @Override
    public List<String> getOutParamNames() {
        return new ArrayList<>(getOutParamsByName().keySet());
    }

    @Override
    public List<Integer> getOutParamIndexes() {
        return new ArrayList<>(getOutParamsByIndex().keySet());
    }

}


Question: package net.ttddyy.dsproxy.asserts.api;
import net.ttddyy.dsproxy.asserts.BatchExecutionEntry;
import net.ttddyy.dsproxy.asserts.CallableBatchExecution;
import net.ttddyy.dsproxy.asserts.CallableBatchExecutionEntry;
import net.ttddyy.dsproxy.asserts.CallableExecution;
import net.ttddyy.dsproxy.asserts.PreparedBatchExecution;
import net.ttddyy.dsproxy.asserts.PreparedBatchExecutionEntry;
import net.ttddyy.dsproxy.asserts.PreparedExecution;
import net.ttddyy.dsproxy.asserts.ProxyTestDataSource;
import net.ttddyy.dsproxy.asserts.QueryExecution;
import net.ttddyy.dsproxy.asserts.StatementBatchExecution;
import net.ttddyy.dsproxy.asserts.StatementExecution;
import javax.sql.DataSource;
import java.sql.JDBCType;
import java.sql.Types;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;




/**
 * API compilation check with assertEquals.
 *
 * @author Tadaya Tsuyukubo
 */
public class SimpleAssertionApiCheck {

    private DataSource actualDataSource;

    public void dataSource() {
        // tag::datasource[]
        ProxyTestDataSource ds = new ProxyTestDataSource(actualDataSource);

        // ... perform application logic with database ...

        // execution count
        assertEquals(3, ds.getQueryExecutions().size());
        assertEquals(3, ds.getStatements().size());
        assertEquals(3, ds.getBatchStatements().size());
        assertEquals(3, ds.getPrepareds().size());
        assertEquals(3, ds.getBatchPrepareds().size());
        assertEquals(3, ds.getCallables().size());
        assertEquals(3, ds.getBatchCallables().size());
        // end::datasource[]
    }

    public void queryExecution() {
        // tag::query[]
        ProxyTestDataSource ds = new ProxyTestDataSource(actualDataSource);

        // ... perform application logic with database ...

        // each execution
        QueryExecution qe = ds.getQueryExecutions().get(0);
        assertTrue(qe.isSuccess());
        assertTrue(qe.isBatch());
        assertTrue("is statement", qe instanceof StatementExecution);
Answer:         assertTrue("is batch statement", qe instanceof StatementBatchExecution);