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:
parent
426a1fdfd4
commit
95e6019c12
2 changed files with 330 additions and 0 deletions
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue