2011-06-07 15 views
22

Tengo el código donde llene el conjunto de resultados con CallableStatement.executeQuery(). Me he burlado de ResultSet y CallableStatement, pero para probar el método tengo que completar ResultSet.cómo simular el conjunto de resultados y poblarlo usando Mockito en Java

Este es el código del método que estoy probando

ResultSet rset = cs.executeQuery(); 
while (rset.next()) { 
IndexVolatilityImpl tsImpl = new IndexVolatilityImpl(); 
tsImpl.setTradeDate(rset.getString("trade_date")); 
tsImpl.setTradeTime(rset.getString("trade_time")); 
tsImpl.setExprDate(rset.getString("expr_date")); 
tsImpl.setSymbol(rset.getString("symbol")); 
tsImpl.setTradePrice(rset.getDouble("trade_price")); 
tsImpl.setContractMonth(rset.getString("contract_month")); 
tsImpl.setMilliSecs(rset.getString("trade_time_thou")); 
colIndexVolatilityImpl.add(tsImpl); 

he burlado de la CallableStatement y conjunto de resultados, ya que ahora son objeto de burla mi rseto viene con las manos vacías. Me gustaría llenar conjunto de resultados y hacerlo de la siguiente manera

resultSetMock = Mockito.mock(ResultSet.class); 
Mockito.when(resultSetMock.getString("trade_date")).thenReturn("03/10/2011"); 
Mockito.when(resultSetMock.getString("trade_time")).thenReturn("12:24:56"); 
Mockito.when(resultSetMock.getString("expr_date")).thenReturn("03/19/2011"); 
Mockito.when(resultSetMock.getString("symbol")).thenReturn("VIX1"); 
Mockito.when(resultSetMock.getDouble("trade_price")).thenReturn(Double.valueOf("20.96")); 
Mockito.when(resultSetMock.getString("contract_month")).thenReturn("1"); 
Mockito.when(resultSetMock.getString("trade_time_thou")).thenReturn("165"); 

Mockito.doReturn(resultSetMock).when(callableStatementMock).executeQuery(); 

Pero de resultados cheques a ser nulo.

Por lo tanto, cualquier ayuda será apreciada para ayudar a poblar resultados simulados.

Gracias Tejas

+0

mejor respuesta está en el fondo y tiene más de 24 upvotes por @proactif – nanospeck

Respuesta

27

También debe burlarse del método next() para que se devuelva true la primera vez que se llama, como Mockito devolverá false por defecto.

Mockito.when(resultSetMock.next()).thenReturn(true).thenReturn(false); 
+2

que estoy haciendo eso, pero me gustaría Llenar conjunto de resultados y estoy haciendo como se describe más arriba, pero que sale a nulo. ¿Puedes por favor arrojar luz qué estoy haciendo mal? –

+0

Acabo de probar un código de prueba similar y funcionó. Entonces, ¿tu respuesta es nula? Supongo que el objeto cs es, por supuesto, el callableStatementMock, en cuyo caso debería funcionar. Pensé que tu problema era solo que tu RS estaba vacío, pero no veo cómo puede ser nulo. – proactif

4

He escrito algo para este mismo asunto. Puede simular el conjunto de resultados usando Mockito. También puede recorrer las filas simuladas del conjunto de resultados burlándose del conjunto de resultados.next() con este fragmento de código.

// two dimensional array mocking the rows of database. 
String[][] result = { { "column1", "column2" }, { "column1", "column2" } }; 

@InjectMocks 
@Spy 
private TestableClass testableClass; 

@Mock 
private Connection connection; 

@Mock 
private Statement statement; 

@Mock 
private ResultSet resultSet; 

@BeforeTest 
public void beforeTest() { 
    MockitoAnnotations.initMocks(this); 
} 

@BeforeMethod 
public void beforeMethod() throws SQLException { 
    doAnswer(new Answer<Connection>() { 
     public Connection answer(InvocationOnMock invocation) 
       throws Throwable { 
      return connection; 

     } 
    }).when(testableClass).getConnection(); 

    when(connection.createStatement()).thenReturn(statement); 
    when(statement.executeQuery(anyString())).thenReturn(resultSet); 
    final AtomicInteger idx = new AtomicInteger(0); 
    final MockRow row = new MockRow(); 

    doAnswer(new Answer<Boolean>() { 

     @Override 
     public Boolean answer(InvocationOnMock invocation) throws Throwable { 
      int index = idx.getAndIncrement(); 
      if (result.length <= index) { 
       return false; 
      } 
      String[] current = result[index]; 
      row.setCurrentRowData(current); 
      return true; 

     } 

     ; 
    }).when(resultSet).next(); 

    doAnswer(new Answer<String>() { 

     @Override 
     public String answer(InvocationOnMock invocation) throws Throwable { 
      Object[] args = invocation.getArguments(); 
      int idx = ((Integer) args[0]).intValue(); 
      return row.getColumn(idx); 
     } 

     ; 
    }).when(resultSet).getString(anyInt()); 
} 

static class MockRow { 
    String[] rowData; 

    public void setCurrentRowData(String[] rowData) { 
     this.rowData = rowData; 
    } 

    public String getColumn(int idx) { 
     return rowData[idx - 1]; 
    } 
} 
+0

¿por qué hiciste la clase MockRow? –

+0

@UmerHayat: es una encapsulación limpia sobre una representación de matriz. –

2

Reescribí @karthik m de responder un poco para que el conjunto de resultados independiente burlador:

Utilizando la clase más adelante puedo exportar el resultado de una consulta como CSV y escribir una prueba alrededor de eso.

No se burlan todos los métodos del ResultSet, ya que no los necesitaba, pero deberían ser bastante triviales.

import no.di.common.util.StringUtil; 
import org.apache.commons.io.FileUtils; 
import org.apache.commons.io.LineIterator; 
import org.mockito.invocation.InvocationOnMock; 
import org.mockito.stubbing.Answer; 

import java.io.File; 
import java.io.IOException; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.concurrent.atomic.AtomicInteger; 

import static org.mockito.Matchers.anyInt; 
import static org.mockito.Matchers.anyString; 
import static org.mockito.Mockito.doAnswer; 
import static org.mockito.Mockito.mock; 

/** 
* Creates a Mock of a ResultSet 
*/ 
public class ResultSetMocker { 

    private Map<String, Integer> columnNames = new HashMap<>(); 

    private Object[][] result; 

    public ResultSetMocker(String filename) throws IOException { 
     loadData(filename); 
    } 

    private void loadData(String filename) throws IOException { 
     List<Object[]> toRet = new ArrayList<>(); 

     int numberOfParts = 0; 
     LineIterator it = FileUtils.lineIterator(new File(filename), "ISO8859-1"); 
     try { 
      String names = it.nextLine(); 
      String[] name = names.split(";"); 
      for(int i = 0; i < name.length; i++) { 
       columnNames.put(name[i], i + 1); 
      } 

      while (it.hasNext()) { 
       String line = it.nextLine(); 

       String[] parts = line.split(";"); 
       numberOfParts = parts.length; 
       Object[] result = new Object[parts.length]; 
       for(int i = 0; i < parts.length; i++) { 
        if(parts[i].equals("(null)")) 
         result[i] = null; 
        else if(StringUtil.isAllNumeric(parts[i])) 
         result[i] = Integer.parseInt(parts[i]); 
        else 
         result[i] = parts[i]; 
       } 

       toRet.add(result); 
      } 
     } finally { 
      it.close(); 
     } 

     result = toRet.toArray(new Object[toRet.size()][numberOfParts]); 
    } 

    public ResultSet getResultSet() throws SQLException, IOException { 
     ResultSet resultSet = mock(ResultSet.class); 

     final AtomicInteger idx = new AtomicInteger(0); 
     final MockRow row = new MockRow(columnNames); 

     doAnswer(new Answer<Boolean>() { 
      @Override 
      public Boolean answer(InvocationOnMock invocation) throws Throwable { 
       int index = idx.getAndIncrement(); 
       if (result.length > index) { 
        row.setCurrentRowData(result[index]); 
        return true; 
       } else 
        return false; 
      } 
     }).when(resultSet).next(); 

     doAnswer(new Answer<String>() { 
      @Override 
      public String answer(InvocationOnMock invocation) throws Throwable { 
       Object[] args = invocation.getArguments(); 
       int idx = (Integer) args[0]; 
       return row.getString(idx); 
      } 
     }).when(resultSet).getString(anyInt()); 

     doAnswer(new Answer<String>() { 
      @Override 
      public String answer(InvocationOnMock invocation) throws Throwable { 
       Object[] args = invocation.getArguments(); 
       String name = (String) args[0]; 
       return row.getString(name); 
      } 
     }).when(resultSet).getString(anyString()); 

     doAnswer(new Answer<Object>() { 
      @Override 
      public Object answer(InvocationOnMock invocation) throws Throwable { 
       Object[] args = invocation.getArguments(); 
       String name = (String) args[0]; 
       return row.getObject(name); 
      } 
     }).when(resultSet).getObject(anyString()); 

     doAnswer(new Answer<Integer>() { 
      @Override 
      public Integer answer(InvocationOnMock invocation) throws Throwable { 
       Object[] args = invocation.getArguments(); 
       String name = (String) args[0]; 
       return row.getInt(name); 
      } 
     }).when(resultSet).getInt(anyString()); 

     return resultSet; 
    } 

    static class MockRow { 
     Object[] rowData; 
     private Map<String, Integer> columnNames; 

     public MockRow(Map<String, Integer> columnNames) { 

      this.columnNames = columnNames; 
     } 

     public void setCurrentRowData(Object[] rowData) { 
      this.rowData = rowData; 
     } 

     public String getString(int idx) { 
      return (String)rowData[idx - 1]; 
     } 

     public String getString(String name) { 
      return (String)rowData[columnNames.get(name) - 1]; 
     } 

     public Object getObject(String name) { 
      return rowData[columnNames.get(name) - 1]; 
     } 

     public Integer getInt(String name) { 
      return (Integer)rowData[columnNames.get(name) - 1]; 
     } 
    } 
} 
Cuestiones relacionadas