How to stub/mock JDBC ResultSet to work both with Java 5 and 6?

12,869

Well, after some thinking I ended up having the stub class as there and mocking it with Mockito as:

public static ResultSet initMock(Object[][] data) throws SQLException {
    final StubResultSetContents contents = new StubResultSetContents(data);
    ResultSet rs = mock(ResultSet.class, RETURNS_SMART_NULLS);
    when(rs.getObject(anyInt())).thenAnswer(new Answer<Object>() {
        public Object answer(InvocationOnMock invocation) throws Throwable {
            return contents.getObject(getIntArgument(invocation));
        }
    });
    // a bunch of similar when(...).thenAnswer(...) constructs...
}

(stub class in StubResultSetContents). If somebody has some other ideas, feel free to answer =)

Share:
12,869
Apollon
Author by

Apollon

Updated on June 12, 2022

Comments

  • Apollon
    Apollon almost 2 years

    I'm testing some of my classes working with JDBC statements etc and now I got problem with JDBC ResultSet interface:

    The software should run both with Java 5 and Java 6 and hence the tests should also be run with both versions. Unfortunately Java 6 has introduced a bunch of new methods (which is still not a big deal) that return a bunch of new classes/interfaces, which makes the things more difficult. (see Frank Carver’s Punch Barrel - Java 6 breaks JDBC for example)

    Before finding out these version differences, I considered between stubbing and mocking and ended up with stubbing because the ResultSet has internal state (current row handled) that is more natural to me to work with stubs, as :

    public class StubResultSet implements ResultSet {
        private Object[][] data;
        private int currentRow = -1;
        private boolean closed = false;
    
        public StubResultSet(Object[][] data) {
            this.data = data;
        }
    
        public Object getObject(int columnIndex) throws SQLException {
            checkClosed();
            return data[currentRow][columnIndex];
        }
        public String getString(int columnIndex) throws SQLException {
            checkClosed();
            return (String) getObject(columnIndex);
        }
    
        // ...
    }
    

    But if I don't introduce the new methods as public NClob getNClob(int columnIndex), the class is broken under Java 6 - if I introduce them the class in broken under Java 5.

    I can work with mockito (for example) callbacks to have the state being reflected with the return values but does somebody have some other - maybe more nice - idea?