2011-09-01 21 views
5

Mam metodę na jednej z klas w mojej bazie kodu, która dla mojego życia nie może się zetknąć z moimi testami junit. Zasadniczo ta klasa nazywa kiedy poprosić o połączenie z bazą danych, jeśli nieświeże połączenie zostanie zwrócony, nowe połączenie zostanie nawiązaneJava - Code Coverage

Oto urywek mthod w mojej klasie (okrojone do tego celu)

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; 
}} 

Każdy pomysł, w jaki sposób mogę zagwarantować, że moje testy w trybie junit wykonają instrukcję if? Obecnie używam EasyMock i Powermock ale nie mogę znaleźć sposób, aby dostać się do tego, czy statment pomocą tych narzędzi

Każda pomoc jest mile widziana

Dziękujemy Damien

Odpowiedz

8

Należy byłaby swoją klasę stać się proxy dla innego źródła danych, zamiast dziedziczyć z jednego. W ten sposób można łatwo wprowadzić do niej fałszywe źródło danych zamiast rzeczywistego.

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

jeden pomysł do głowy: użycie agregacji zamiast dziedziczenia. Ten problem i inne podobałyby mu się, ponieważ można wtedy kpić z zagregowanego obiektu, aby mieć jakikolwiek pożądany przez ciebie styl. Nie widzę innego sposobu, żeby się tam dostać. W rzeczywistości nazwa TCSOracleDataSourceWrapper już wskazuje, że owija źródło danych (agregację), gdy tak naprawdę nie jest.

1

Jednym z szybkich obejść jest wyodrębnienie połączenia super.getConnection() do nowej metody prywatnej/chronionej. Po wprowadzeniu tej zmiany łatwo będzie wyśmiać metodę getBaseConnection przy pomocy makiety zasilania. To jest krótkoterminowa poprawka, podobnie jak inne odpowiedzi sugerują, że lepiej jest używać delegacji zamiast dziedziczenia dla implementacji opakowania.

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; 
}