Mock result set class

* Added a mock result set class which can be used to write unit tests
for e.g. RowMapper-based classes. The class is incomplete and should be
extended as necessary.

* Added unit test for BuildingsInformationMapper as a proof of concept
This commit is contained in:
Emmanuel BENOîT 2012-01-17 16:47:05 +01:00
parent 426a1fdfd4
commit 95e6019c12
2 changed files with 330 additions and 0 deletions

View file

@ -0,0 +1,81 @@
package com.deepclone.lw.beans.bt.es;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import com.deepclone.lw.beans.bt.es.data.BuildingsInformation;
import com.deepclone.lw.testing.MockResultSet;
/**
* Tests for the {@link BuildingsInformationMapper} class.
*/
public class TestBuildingsInformationMapper
{
/** Planet identifier found in the "result" */
private static final int PLANET_ID = 1;
/** Building identifier found in the "result" */
private static final int BUILDING_ID = 2;
/** Name found in the "result" */
private static final String BUILDING_NAME = "Test";
/** Quantity of buildings found in the "result" */
private static final int QUANTITY = 3;
/** Damage value found in the "result" */
private static final double DAMAGE = 4.0;
/** The fake result set used in the tests */
private ResultSet resultSet;
/** The mapper used in the tests */
private BuildingsInformationMapper mapper;
/**
* Create the contents of the fake result set
*/
@Before
@SuppressWarnings( "unchecked" )
public void setUp( )
{
HashMap< String , Object > row = new HashMap< String , Object >( );
row.put( "planet_id" , PLANET_ID );
row.put( "building_id" , BUILDING_ID );
row.put( "building_name" , BUILDING_NAME );
row.put( "amount" , QUANTITY );
row.put( "damage" , DAMAGE );
this.resultSet = MockResultSet.create( new HashMap[] {
row
} );
this.mapper = new BuildingsInformationMapper( );
}
/**
* The row mapper returns an instance that contains the necessary data.
*/
@Test
public void testRowMapper( )
throws SQLException
{
this.resultSet.absolute( 1 );
BuildingsInformation info = this.mapper.mapRow( this.resultSet , 0 );
assertNotNull( info );
assertEquals( PLANET_ID , info.getPlanetId( ) );
assertEquals( BUILDING_ID , info.getId( ) );
assertEquals( BUILDING_NAME , info.getName( ) );
assertEquals( QUANTITY , info.getAmount( ) );
assertEquals( DAMAGE , info.getDamage( ) , 0 );
}
}

View file

@ -0,0 +1,249 @@
package com.deepclone.lw.testing;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
/**
* Mock result set
*
* <p>
* This class uses a proxy to mock a {@link ResultSet} instance. It can be used in unit tests to
* fake SQL operation results.
*
* <p>
* FIXME: for now, this class is mostly empty. It will be filled as necessary when writing tests.
*
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
*/
public class MockResultSet
implements InvocationHandler
{
/** The rows in this result set */
private final HashMap< String , Object >[] rows;
/** The current row's index */
private int index = -1;
/** Last read column was <code>null</code>? */
private boolean nullFound = false;
/**
* Initialise the result set's rows.
*
* @param rows
* an array of hash tables that will be returned when trying to access the result set
*/
private MockResultSet( HashMap< String , Object >[] rows )
{
this.rows = rows;
}
@Override
public Object invoke( Object proxy , Method method , Object[] args )
throws Throwable
{
Method m = MockResultSet.class.getMethod( method.getName( ) , method.getParameterTypes( ) );
if ( m == null ) {
throw new SQLException( "Unsupported method " + method.getName( ) );
}
return m.invoke( this , args );
}
/**
* Create a mock result set
*
* @param rows
* the values that will be returned by the result set
*
* @return a mock result set
*/
public static ResultSet create( HashMap< String , Object >[] rows )
{
return (ResultSet) Proxy.newProxyInstance( ResultSet.class.getClassLoader( ) , new Class[] {
ResultSet.class
} , new MockResultSet( rows ) );
}
/**
* Move the cursor to some row
*
* @param row
* the row to select
*
* @return <code>true</code> if the cursor is inside the fake result, <code>false</code> if it
* isn't.
*/
public boolean absolute( int row )
{
if ( row < 0 ) {
row = this.rows.length + row;
} else {
row--;
}
if ( row < 0 ) {
this.index = -1;
return false;
}
if ( row >= this.rows.length ) {
this.index = this.rows.length - 1;
return false;
}
this.index = row;
return true;
}
/**
* Access the next "row"
*
* <p>
* If there are more "rows" available, move to the next one.
*
* @return <code>true</code> if there are more rows, <code>false</code> if there aren't.
*/
public boolean next( )
{
if ( this.index < this.rows.length ) {
this.index++;
}
return this.index < this.rows.length;
}
/**
* Check if the last value accessed contained NULL
*
* @return <code>true</code> if it did, <code>false</code> if it didn't
*/
public boolean wasNull( )
{
return this.nullFound;
}
/**
* Return the object in some column of the current "row"
*
* @param columnName
* the column's name
*
* @return the object from the fake results
*
* @throws SQLException
* if no row is selected
*/
public Object getObject( String columnName )
throws SQLException
{
if ( this.index < 0 || this.index >= this.rows.length ) {
throw new SQLException( "Current row is out of bounds" );
}
Object object = this.rows[ this.index ].get( columnName );
this.nullFound = ( object == null );
return object;
}
/**
* Return the object in some column of the current "row" as a string
*
* @param columnName
* the column's name
*
* @return the object from the fake results, as a string
*
* @throws SQLException
* if no row is selected
*/
public String getString( String columnName )
throws SQLException
{
Object object = this.getObject( columnName );
if ( object != null ) {
return object.toString( );
}
return null;
}
/**
* Return the object in some column of the current "row" as a boolean
*
* @param columnName
* the column's name
*
* @return the object from the fake results, as a boolean
*
* @throws SQLException
* if no row is selected
*/
public boolean getBoolean( String columnName )
throws SQLException
{
Object object = this.getObject( columnName );
if ( object != null ) {
return (Boolean) object;
}
return false;
}
/**
* Return the object in some column of the current "row" as an integer
*
* @param columnName
* the column's name
*
* @return the object from the fake results, as an integer
*
* @throws SQLException
* if no row is selected
*/
public int getInt( String columnName )
throws SQLException
{
Object object = this.getObject( columnName );
if ( object != null ) {
return (Integer) object;
}
return 0;
}
/**
* Return the object in some column of the current "row" as a double
*
* @param columnName
* the column's name
*
* @return the object from the fake results, as a double
*
* @throws SQLException
* if no row is selected
*/
public double getDouble( String columnName )
throws SQLException
{
Object object = this.getObject( columnName );
if ( object != null ) {
return (Double) object;
}
return 0;
}
}