2009-05-28 10 views
6

Я тестирую некоторые из моих классов, работающих с JDBC заявлений и т.д., и теперь я получил проблему с интерфейсом ResultSet JDBC:Как заглушить/mock JDBC ResultSet для работы как с Java 5, так и с 6?

Программное обеспечение должно выполняться как с Java 5 и Java 6 и, следовательно, тесты должны также работать с обоими версии. К сожалению, Java 6 представила множество новых методов (которые все еще не очень важны), которые возвращают кучу новых классов/интерфейсов, что усложняет ситуацию. (см., например, Frank Carver’s Punch Barrel - Java 6 breaks JDBC)

Прежде чем узнавать эти различия в версиях, я рассматривал это между stubbing и mocking и заканчивал с stubbing, потому что ResultSet имеет внутреннее состояние (текущая строка обрабатывается), что более естественно для меня работать с заглушками, как:

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

    // ... 
} 

Но если я не вводить новые методы, как public NClob getNClob(int columnIndex), класс разбивается под Java 6 - если я ввожу их класс в разбитой под Java 5.

я могу работать с mockito (например) обратные вызовы для отражения состояния с возвратной оценкой но у кого-то есть какая-то другая - может быть, более приятная идея?

ответ

3

Ну, после некоторого мышления я закончил тем, что класс заглушки, как там и насмешливый его с Mockito как:

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

(класс заглушки в StubResultSetContents). Если у кого-то есть другие идеи, не стесняйтесь отвечать =)

0

У меня была такая же проблема и была решена с помощью реализации прокси. Кажется, он работает очень хорошо.

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

} 

 Смежные вопросы

  • Нет связанных вопросов^_^