2009-05-28 33 views
6

Tôi đang thử nghiệm một số lớp của mình đang làm việc với các câu lệnh JDBC vv và bây giờ tôi gặp vấn đề với giao diện JDBC ResultSet:Làm thế nào để stub/mock JDBC ResultSet để làm việc cả với Java 5 và 6?

Phần mềm sẽ chạy cả với Java 5 và Java 6 và do đó các thử nghiệm cũng nên được chạy với cả hai phiên bản. Thật không may Java 6 đã giới thiệu một loạt các phương thức mới (mà vẫn không phải là một vấn đề lớn) mà trả về một loạt các lớp/giao diện mới, làm cho mọi thứ trở nên khó khăn hơn. (xem Frank Carver’s Punch Barrel - Java 6 breaks JDBC chẳng hạn)

Trước khi tìm ra những khác biệt trong phiên bản này, tôi đã cân nhắc giữa việc đặt hàng và chế nhạo và kết thúc bằng việc đặt trước vì ResultSet có trạng thái bên trong (hàng hiện tại được xử lý). như:

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

    // ... 
} 

Nhưng nếu tôi không giới thiệu các phương pháp mới như public NClob getNClob(int columnIndex), lớp được chia dưới Java 6 - nếu tôi giới thiệu cho họ những lớp trong bị phá vỡ dưới Java 5.

tôi có thể làm việc với mockito (ví dụ) callbacks để có trạng thái được phản ánh với valu trả về es nhưng ai đó có một số khác - có lẽ tốt hơn - ý tưởng?

Trả lời

3

Vâng, sau khi một số suy nghĩ tôi đã kết thúc có lớp stub như ở đó và chế giễu nó với Mockito như:

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... 
} 

(lớp còn sơ khai trong StubResultSetContents). Nếu ai đó có một số ý tưởng khác, hãy trả lời =)

0

Tôi đã gặp sự cố tương tự và đã giải quyết vấn đề đó bằng cách triển khai Proxy. Có vẻ như nó hoạt động khá tốt.

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

} 
Các vấn đề liên quan