2011-09-01 17 views
5

Tengo un método en una de las clases en mi base de código que por mi vida, no puedo entrar con mis pruebas junit. Básicamente esta clase se llama cuando solicito una conexión de base de datos, si se devuelve una conexión en punto muerto, se establece una nueva conexiónJava - Code Coverage

Aquí es el fragmento de la mthod en mi clase (recortada para este propósito)

public class TCSOracleDataSourceWrapper extends OracleDataSource { 

private static final int STALE_CONNECTION_EX_CODE = 17143; 
private OracleConnectionCacheManager cacheManager; 
private String cacheName; 
/** Local log variable **/ 
private final Log logger = LogFactory.getLog(getClass()); 


/** 
* Class constructor 
* @throws SQLException 
*/ 
public TCSOracleDataSourceWrapper() throws SQLException { 
    super(); 
} 

private static final long serialVersionUID = 1L; 

@Override 
/** 
* Get a connection but if the connection is stale then refresh all DB connections 
* 
*/ 
public final Connection getConnection() throws SQLException { 

    logger.debug("Retrieving a database connection from the pool"); 

    Connection connection = null; 
    try{ 
     connection = super.getConnection();   
    } 
    catch(SQLException e) 
    { 

     if(e.getErrorCode() == STALE_CONNECTION_EX_CODE) 
     {    
      logger.error("Stale Oracle connection found in the Connection Pool. Refreshing invalid DB connections."); 
      //refresh invalid connections 
      cacheManager.refreshCache(cacheName, OracleConnectionCacheManager.REFRESH_INVALID_CONNECTIONS); 
      //now try to get the connection again 
      connection = super.getConnection(); 
     } 
     else 
     { 
      throw e; 
     } 
    }  

    return connection; 
}} 

¿Alguna idea de cómo puedo garantizar que mis pruebas junit ejecuten la instrucción if? actualmente estoy usando EasyMock y Powermock pero no puedo encontrar una manera de entrar en esto si DECLARACIÓN uso de estas herramientas

Toda ayuda es muy apreciada

Gracias Damien

Respuesta

8

Debe refactorizar su clase con el fin conviértase en proxy para otra fuente de datos, en lugar de heredar de una. De esta forma, puede inyectar fácilmente una fuente de datos simulada en lugar de la fuente real.

import javax.sql.DataSource; 

public class TCSOracleDataSourceWrapper implements DataSource { 
    ... 
    private DataSource wrappedDataSource; 
    ... 

    public TCSOracleDataSourceWrapper(DataSource ds) { 
    wrappedDataSource = ds; 
    } 

    ... 

    public final Connection getConnection() throws SQLException { 
    ... 

    Connection connection = null; 
    try{ 
     connection = ds.getConnection();   
    } 
    catch(SQLException e) 
    { 
     ... 
    }  

    return connection; 
    } 
} 
3

Una idea viene a la mente: utilizar la agregación en lugar de la herencia. Este problema y otros similares desaparecerían porque luego puede simular que el objeto agregado tiene el comportamiento que desee. No veo otra forma de entrar allí de inmediato. De hecho, el nombre TCSOracleDataSourceWrapper ya indica que está envolviendo un origen de datos (agregación), cuando en realidad no lo está.

1

Una solución rápida consiste en factorizar la llamada a super.getConnection() a un nuevo método privado/protegido. Una vez que haga ese cambio, sería fácil burlarse del método getBaseConnection utilizando power mock. Esta es la solución a corto plazo, al igual que las otras respuestas sugieren que es mejor usar la delegación en lugar de la herencia para la implementación del reiniciador.

Connection getBaseConnection() throws SQLException { 
    return super.getConnection(); 
} 

public final Connection getConnection() throws SQLException { 

    logger.debug("Retrieving a database connection from the pool"); 

    Connection connection = null; 
    try{ 
     connection = getBaseConnection();   
    } 
    catch(SQLException e) 
    { 

     if(e.getErrorCode() == STALE_CONNECTION_EX_CODE) 
     {    
      logger.error("Stale Oracle connection found in the Connection Pool. Refreshing invalid DB connections."); 
      //refresh invalid connections 
      cacheManager.refreshCache(cacheName, OracleConnectionCacheManager.REFRESH_INVALID_CONNECTIONS); 
      //now try to get the connection again 
      connection = getBaseConnection(); 
     } 
     else 
     { 
      throw e; 
     } 
    }  
    return connection; 
}