'Mock ResultSet with Mockito
How to mock the resultset?
In the test class trying to mock the resultset as below but, when trying to test getting error as UnnecessaryStubbingException
at statements :
voObj.setDept(rs.getString(2));
and
voObj.setDeptDesc(rs.getString(3));
Any suggessions on how to mock the resultset?
public class Example {
public static void main(String[] s) {
method1();
method2();
..........
}
private Employee method1(String str) {
Connection conn = getConnection();
PreparedStatement pstmt = null;
.........
pstmt = conn.prepareStatement(strQuery.toString());
rs = pstmt.executeQuery();
int ilCounter = 0;
int maxId = method2(loc); //some DB calls here with select
if(null != rs) {
while(rs.next()) {
ilCounter++;
ObjVoBean voObj = new ObjVoBean();
voObj.setLoc(rs.getString(1));
voObj.setDept(rs.getString(2));
voObj.setDeptDesc(rs.getString(3));
}
.................
}
}
private Employee method2(String str1) {
Connection connOHM = getConnection();
PreparedStatement pstmt = null;
.........
//some DB call with select ...
}
}
public class ExampleTest {
@InjectMocks
Example example;
@Mock
private Connection c;
@Mock
private PreparedStatement preStmt;
.....
@Before
public void setUp() {
........
}
@Test
public void testMethod1() throws SQLException {
ResultSet resultSetMock = Mockito.mock(ResultSet.class);
when(resultSetMock.getString(1)).thenReturn("1111");
when(resultSetMock.getString(2)).thenReturn("2222");
when(resultSetMock.getString(3)).thenReturn("dept desc");
when(c.prepareStatement(any(String.class))).thenReturn(preStmt);
when(resultSetMock.next()).thenReturn(true).thenReturn(false);
doReturn(resultSetMock).when(preStmt).executeQuery();
example.method1("1111");
assertTrue(true);
}
}
Solution 1:[1]
To be able to mock the ResultSet
you should mock all objects that allow to create it that is Connection
that creates the PreparedStatement
, that itself creates the ResultSet
.
Mocking the Connection will work in the tested code only if you provide a way to set the connection from the client code.
Here conn
that is the Connection should be first injected as a dependency in your test fixture :
pstmt = conn.prepareStatement(strQuery.toString());
Generally you create a Connection
such as :
conn = DriverManager.getConnection(DB_URL,USER,PASS);
or via a DataSource
such as :
conn = ds.getConnection();
So you should abstract this part into an interface or a not final class and define an implementation that do this processing. In this way you can mock the part that creates a Connection. And so you can mock the whole chain : Connection-PreparedStatement-ResultSet.
Personally I would avoid this way because mocking too many things is often not the right choice.
In your case, what you need is mocking the ResultSet to test the post processing after loading the ResultSet :
while(rs.next()) {
ilCounter++;
ObjVoBean voObj = new ObjVoBean();
voObj.setLoc(rs.getString(1));
voObj.setDept(rs.getString(2));
voObj.setDeptDesc(rs.getString(3));
}
So as alternative you could move all code performed before in a method of specific class handling the persistence part. In this way you just need to mock this dependency and this method. You don't need to worry about Connection and any JDBC detail.
EmployeeDAO employeeDAO; // dependency to mock
// constructor with dependency
public Example(EmployeeDAO employeeDAO){
this.employeeDAO = employeeDAO;
}
private Employee method1(String str) {
ResultSet resultSet = employeeDAO.load(str);
if(null != rs) {
while(rs.next()) {
ilCounter++;
ObjVoBean voObj = new ObjVoBean();
voObj.setLoc(rs.getString(1));
voObj.setDept(rs.getString(2));
voObj.setDeptDesc(rs.getString(3));
}
.................
}
}
Of couse the DAO components also have to be unitary tested.
Bu as said earlier, asserting that a Connection
is created or that it returns a PreparedStatement
does not bring value. While testing that your queries perform what you expect from them is much more interesting in terms of functional coverage.
In this case, you want to test it against an in-memory DB such as H2 because unit tests are not integration tests and unit tests have to be fast executed.
To write DAO/Repository tests, Dbunit and DbSetup are good candidates because they provide facilities to setup the DB before each test (mainly injecting data and clearing data).
Solution 2:[2]
This is a mock Result Set I ripped off of GitHub
/*
* Distributed under the terms of the MIT License.
* Copyright (c) 2009, Marcelo Criscuolo.
*/
package commondb.mock;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import org.apache.commons.lang.StringUtils;
public class MockResultSet implements ResultSet {
static final String INVALID_COLUMN_NAME = "invalid column name";
static final String INVALID_COLUMN_INDEX = "invalid column index";
static final DateFormat DATE_ISO_8601 = new SimpleDateFormat("yyyy-MM-dd");
private List<String[]> rowset = new ArrayList<String[]>();
private int cursor = -1;
private Map<String, Integer> columnMap = new HashMap<String, Integer>();
private CSVLineSplitter splitter = new CSVLineSplitter();
public MockResultSet() {
}
/**
* ResultSet rs = new MockResultSet(
* "ID,NAME,CITY",
* "3,John,New York",
* "4,Bill,Sydney"
* );
*
* @param str headers and rows that form the CSV data
*/
public MockResultSet(String... str) throws SQLException {
loadCSV(new StringReader(StringUtils.join(str, "\n")));
}
/**
* @param in source from where the CSV data will be read
*
* @throws SQLException any exception will be wrapped
* on SQLException, so that it is not necessary to
* add additional catches to client code.
*/
public MockResultSet(Readable in) throws SQLException {
loadCSV(in);
}
public void loadCSV(Readable in) throws SQLException {
final Scanner sc = new Scanner(in);
if (!sc.hasNextLine()) {
sc.close();
throw new SQLException("empty data source");
}
// load column headers
String line = sc.nextLine();
int index = 1;
for (String column : splitter.split(line)) {
columnMap.put(column, index);
index++;
}
// load data
while (sc.hasNextLine()) {
line = sc.nextLine();
String[] row = splitter.split(line);
rowset.add(row);
}
sc.close();
}
@Override
public boolean absolute(int row) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void afterLast() throws SQLException {
cursor = rowset.size();
}
@Override
public void beforeFirst() throws SQLException {
cursor = -1;
}
@Override
public void cancelRowUpdates() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void clearWarnings() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void close() throws SQLException {
// noop
}
@Override
public void deleteRow() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public int findColumn(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean first() throws SQLException {
if (rowset.size() > 0) {
cursor = 0;
return true;
}
return false;
}
@Override
public Array getArray(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Array getArray(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public InputStream getAsciiStream(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
@Deprecated
public BigDecimal getBigDecimal(int columnIndex, int scale)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
@Deprecated
public BigDecimal getBigDecimal(String columnLabel, int scale)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public InputStream getBinaryStream(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Blob getBlob(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Blob getBlob(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean getBoolean(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean getBoolean(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public byte getByte(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public byte getByte(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public byte[] getBytes(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Reader getCharacterStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Reader getCharacterStream(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Clob getClob(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Clob getClob(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public int getConcurrency() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public String getCursorName() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
/**
* Dates are expected to be formatted as yyyy-MM-dd.
* See http://en.wikipedia.org/wiki/ISO_8601#Calendar_dates
*/
public Date getDate(int columnIndex) throws SQLException {
try {
String value = getValue(columnIndex);
Date date = null;
if ( (value != null) && (value.trim().length() >= 0)) {
date = new Date(DATE_ISO_8601.parse(value).getTime());
}
return date;
} catch (Exception e) {
throw new SQLException(e);
}
}
@Override
public Date getDate(String columnLabel) throws SQLException {
return getDate(getColumnIndex(columnLabel));
}
@Override
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public double getDouble(int columnIndex) throws SQLException {
try {
String value = getValue(columnIndex);
if ( (value == null) || (value.trim().length() == 0)) {
value = "0";
}
value = value.replace(',', '.');
return Double.parseDouble(value);
} catch (Exception e) {
throw new SQLException(e);
}
}
@Override
public double getDouble(String columnLabel) throws SQLException {
return getDouble(getColumnIndex(columnLabel));
}
@Override
public int getFetchDirection() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public int getFetchSize() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public float getFloat(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public float getFloat(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public int getHoldability() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public int getInt(int columnIndex) throws SQLException {
try {
String value = getValue(columnIndex);
if ( (value == null) || (value.trim().length() == 0)) {
value = "0";
}
return Integer.parseInt(value);
} catch (Exception e) {
throw new SQLException(e);
}
}
@Override
public int getInt(String columnLabel) throws SQLException {
return getInt(getColumnIndex(columnLabel));
}
@Override
public long getLong(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public long getLong(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public ResultSetMetaData getMetaData() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Reader getNCharacterStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Reader getNCharacterStream(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public NClob getNClob(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public NClob getNClob(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public String getNString(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public String getNString(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Object getObject(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Object getObject(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Object getObject(int columnIndex, Map<String, Class<?>> map)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Object getObject(String columnLabel, Map<String, Class<?>> map)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Ref getRef(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Ref getRef(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public int getRow() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public RowId getRowId(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public RowId getRowId(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public SQLXML getSQLXML(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public SQLXML getSQLXML(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public short getShort(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public short getShort(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Statement getStatement() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public String getString(int columnIndex) throws SQLException {
return getValue(columnIndex);
}
private String getValue(int columnIndex) throws SQLException {
if ( (cursor < 0) || (cursor >= rowset.size()) ) {
throw new SQLException("cursor not pointing to a valid row");
}
String[] row = rowset.get(cursor);
if ( (columnIndex < 0) || (columnIndex > row.length) ) {
throw new SQLException(INVALID_COLUMN_INDEX);
}
return row[columnIndex - 1];
}
@Override
public String getString(String columnLabel) throws SQLException {
return getString(getColumnIndex(columnLabel));
}
private Integer getColumnIndex(String columnLabel) throws SQLException {
Integer index = columnMap.get(columnLabel);
if (index == null) {
throw new SQLException(INVALID_COLUMN_NAME);
}
return index;
}
@Override
public Time getTime(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Time getTime(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Timestamp getTimestamp(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Timestamp getTimestamp(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public Timestamp getTimestamp(String columnLabel, Calendar cal)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public int getType() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public URL getURL(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public URL getURL(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
@Deprecated
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
@Deprecated
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public SQLWarning getWarnings() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void insertRow() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean isAfterLast() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean isBeforeFirst() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean isClosed() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean isFirst() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean isLast() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean last() throws SQLException {
if (rowset.size() > 0) {
cursor = rowset.size() - 1;
return true;
}
return false;
}
@Override
public void moveToCurrentRow() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void moveToInsertRow() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean next() throws SQLException {
final boolean hasNext = (cursor + 1) < rowset.size();
if (hasNext) {
cursor++;
}
return hasNext;
}
@Override
public boolean previous() throws SQLException {
cursor--;
if (cursor < -1) {
cursor = -1; // one row before the first is the limit
}
final boolean beforeFirst = (cursor < 0);
return !beforeFirst;
}
@Override
public void refreshRow() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean relative(int rows) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean rowDeleted() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean rowInserted() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public boolean rowUpdated() throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void setFetchDirection(int direction) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void setFetchSize(int rows) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateArray(int columnIndex, Array x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateArray(String columnLabel, Array x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, int length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x, int length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, long length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x, long length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBigDecimal(int columnIndex, BigDecimal x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBigDecimal(String columnLabel, BigDecimal x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, int length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x, int length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, long length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x,
long length) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBlob(int columnIndex, Blob x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBlob(String columnLabel, Blob x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream, long length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream,
long length) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBoolean(String columnLabel, boolean x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateByte(int columnIndex, byte x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateByte(String columnLabel, byte x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateBytes(String columnLabel, byte[] x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateCharacterStream(int columnIndex, Reader x)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, int length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader,
int length) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, long length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader,
long length) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateClob(int columnIndex, Clob x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateClob(String columnLabel, Clob x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateClob(int columnIndex, Reader reader) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateClob(String columnLabel, Reader reader)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateClob(int columnIndex, Reader reader, long length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateClob(String columnLabel, Reader reader, long length)
throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateDate(int columnIndex, Date x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateDate(String columnLabel, Date x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateDouble(int columnIndex, double x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
@Override
public void updateDouble(String columnLabel, double x) throws SQLException {
throw new UnsupportedOperationException("to be implemented");
}
}
Solution 3:[3]
I also wanted to be able to mock a ResultSet with multiple rows and found various answers online but none of them seemed to meet my needs.
In my case I have a class method (SUT) that iterates through a(n) (unknown) number of rows and perform some logic on them (in production runtime). I am trying to ensure that the correct objects that get built from these rows are returned. At test time I know the exact number of rows I am going to examine.
My solution was to @InjectMocks into my my repo class which takes a "factory" connection class that provides the connection via the repo constructor. This is what I did:
import static org.mockito.Mockito.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.SomeStuff.MyRepository;
import com.SomeStuff.MyConnectionFactory;
import com.SomeStuff.Widget;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;
public class MyClass {
@InjectMocks
private MyRepository myRepository;
@Mock
private MyConnectionFactory mcf;
@Mock
private Connection c;
@Mock
private PreparedStatement stmt;
@Mock
private ResultSet rs;
// snipped code below, more to follow
}
then I added a @BeforeEeach to my setup method and inside there comes the secret sauce. In my case I know my code in the SUT wants to iterate through 9 fake rows and I also know that in a couple of cases it only need to work with two rows if they meet certain characteristics.
public class MyClass {
// snipped the previous stuff above
MockitoAnnotations.openMocks(this);
when(mcf.getConnection()).thenReturn(c);
when(c.prepareStatement(any(String.class))).thenReturn(stmt);
when(rs.next())
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(false);
when(rs.getInt("person_id"))
.thenReturn(10001)
.thenReturn(10001)
.thenReturn(10001)
.thenReturn(10001)
.thenReturn(10001)
.thenReturn(10002)
.thenReturn(10002)
.thenReturn(10002)
.thenReturn(10002);
when(rs.getString("first_name"))
.thenReturn("John")
.thenReturn("Dave");
when(rs.getString("last_name"))
.thenReturn("Doe")
.thenReturn("Smith");
when(rs.getString("key_value"))
.thenReturn("Yes")
.thenReturn("")
.thenReturn("8005551212")
.thenReturn("Hello,")
.thenReturn("No")
.thenReturn("")
.thenReturn("")
.thenReturn("World!")
.thenReturn("No");
when(stmt.executeQuery()).thenReturn(rs);
}
Take note that in the above code there is an additional .thenReturn(false) for next or it will never be false. This will cause an infiinte loop if you are while-ing through the rows.
Also notice that in my case my SUT only calls into first_name and last_name twice (as mentioned above, due to other criteria in the rows) so I call thenReturn on it twice (or else there would be 8 calls to it and that won't suit my needs.
Finally I test it like this:
public class MyClass {
// Everything snipped above
@Test
@SneakyThrows
public void getPeople_correct_number_of_Person_is_retrieved() {
List<Person> people = myRepository.getPeople();
assertEquals(1, people.size());
}
}
In my case above I expect one Person to be returned where the 9 rows actually represented characteristics for two people.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Manav Patel |
Solution 3 |