5

I have a method in one of the classes in my code base that for the life of me, I cannot get into with my junit tests. Basically this class is called when I request a database connection, if a stale connection is returned, a new connection is established

Here is the snippet of the mthod in my class (trimmed down for this purpose)

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

Any idea how I can ensure my junit tests execute the if statement? I am currently using EasyMock and Powermock but I cannot find a way to get into this if statment using these tools

All help is greatly appreciated

Thank you Damien

Péter Török
117k31 gold badges277 silver badges332 bronze badges
asked Sep 1, 2011 at 16:20

3 Answers 3

8

You should refactor your class to become a proxy for another data source, rather than inherit from one. This way you can easily inject into it a mock data source instead of the real one.

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;
 }
}
answered Sep 1, 2011 at 16:26

Comments

3

One idea springs to mind: use aggregation rather than inheritance. This problem and others like it would go away because you can then mock the aggregated object to have whatever behavior you want. I don't see another way of getting in there right off hand. In fact, the name TCSOracleDataSourceWrapper already indicates that it's wrapping a data source (aggregation), when it actually isn't.

answered Sep 1, 2011 at 16:27

Comments

1

One quick workaround is to factor out the super.getConnection() call to a new private / protected method. Once you make that change it would be easy to mock the getBaseConnection method using power mock. This is short term fix, like the other answers suggest it is better to use delegation instead of inheritance for the wrapper implementation.

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;
 }
answered Sep 1, 2011 at 16:37

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.