Frage Java - Codeabdeckung


Ich habe eine Methode in einer der Klassen in meiner Code-Basis, die ich für mein Leben nicht mit meinen Junit-Tests aufnehmen kann. Grundsätzlich wird diese Klasse aufgerufen, wenn ich eine Datenbankverbindung anfordere. Wenn eine veraltete Verbindung zurückgegeben wird, wird eine neue Verbindung hergestellt

Hier ist der Ausschnitt der Methode in meiner Klasse (getrimmt für diesen Zweck)

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

Irgendeine Idee, wie ich sicherstellen kann, dass meine Junit-Tests die if-Anweisung ausführen? Ich benutze derzeit EasyMock und Powermock, aber ich finde keine Möglichkeit, dies zu tun, wenn ich diese Tools verwende

Alle Hilfe wird sehr geschätzt

Vielen Dank Damien


5
2017-09-01 16:20


Ursprung


Antworten:


Sie sollten Ihre Klasse umgestalten, um ein Proxy für eine andere Datenquelle, anstatt von einer zu erben. Auf diese Weise können Sie einfach eine falsche Datenquelle anstelle der echten eingeben.

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

8
2017-09-01 16:26



Eine Idee fällt mir ein: Verwenden Sie Aggregation statt Vererbung. Dieses Problem und andere wie es würde verschwinden, weil Sie dann das aggregierte Objekt verspotten können, um das Verhalten zu haben, das Sie wollen. Ich sehe keinen anderen Weg, um direkt von der Hand zu kommen. Tatsächlich bedeutet der Name TCSocralDataSourceWrapper bereits, dass eine Datenquelle (Aggregation) umschlossen wird, wenn dies nicht der Fall ist.


3
2017-09-01 16:27



Eine schnelle Abhilfe besteht darin, den Aufruf von super.getConnection () zu einer neuen privaten / geschützten Methode herauszufiltern. Sobald Sie diese Änderung vorgenommen haben, wäre es leicht, die getBaseConnection-Methode mit Power-Mock zu überspielen. Dies ist eine kurzfristige Lösung, wie die anderen Antworten vorschlagen, ist es besser, Delegierung statt Vererbung für die Wrapper-Implementierung zu verwenden.

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

1
2017-09-01 16:37