Frage

ich einige meiner Klassen Prüfung mit JDBC-Anweisungen arbeiten usw. und jetzt habe ich Problem mit JDBC ResultSet-Schnittstelle:

sollte die Software läuft sowohl mit Java 5 und Java 6 und daher sollen die Tests auch mit beiden Versionen ausgeführt werden. Leider hat Java 6 eine Reihe neuer Methoden eingeführt (die noch keine große Sache ist), die eine Reihe von neuen Klassen / Schnittstellen zurückgeben, die die Dinge erschwert. (Siehe Frank Carver Punch Barrel - Java 6 bricht JDBC zum Beispiel)

Bevor Sie diese Version Unterschiede herauszufinden, als ich zwischen Anstoßen und spöttisch und endete mit stubbing weil der ResultSet hat einen internen Zustand (aktuelle Zeile behandelt), die mehr natürlich für mich ist mit Stubs zu arbeiten, wie:

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

    // ...
}

Aber wenn ich die neuen Methoden wie public NClob getNClob(int columnIndex) nicht vorstellt, wird die Klasse unter Java gebrochen. 6 - wenn ich ihnen die Klasse in gebrochenen unter Java 5 einführen

Ich kann mit Mockito (zum Beispiel) arbeiten Rückrufe den Zustand zu haben, mit den Rückgabewerten reflektiert wird, aber hat jemand eine andere - vielleicht mehr schön - Idee

War es hilfreich?

Lösung

Nun, nach einiger Überlegung ich, da es die Stub-Klasse, die am Ende und verspotten sie mit Mockito wie:

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-Klasse in StubResultSetContents). Wenn jemand ein paar andere Ideen hat, fühlen Sie sich frei zu beantworten =)

Andere Tipps

Ich hatte das gleiche Problem und löste es eine Proxy-Implementierung verwenden. Es scheint, wie es ist ziemlich gut funktioniert.

public class TestResultSet implements InvocationHandler {
    public static ResultSet createProxy(HashMap<Object, Object>[] rows) {
        return (ResultSet) Proxy.newProxyInstance(ResultSet.class.getClassLoader(),
                                             new Class[] { ResultSet.class },
                                             new TestResultSet(rows));
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // Find the equivalent method in the proxy class.
        Method m = TestResultSet.class.getMethod(method.getName(), method.getParameterTypes());
        if(m == null) {
            throw new SQLException("Unsupported method " + method.getName());
        }

        return m.invoke(this, args);
    }

    // Method implementations follow here (only one supplied as an example)

    public boolean isFirst() throws SQLException {
        return index ==0;
    }

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top