I'm unable to mock the close()
method on java.sql.Connection
object. My ultimate goal is to do connection pooling while running JUnit tests. This will eliminate connection overhead during unit testing as the code under test executes connect/close for every SQL request.
I have code snippet which demonstrates the problem. It successfully mocks the connect(), but fails to mock the close()
call. Both connect, and close must be mocked to managed pooled connections.
Since the close()
method does not return a value, I'm using EasyMock.expectLastCall
.
The following code defines the mock, but the print statement for close()
is never executed and my connections are closed.
public class ConnectionPoolTest {
public static final String DATASOURCE_REF = "jdbc/cloudexDS";
public static final String ref = "osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=" + DATASOURCE_REF + ")";
@BeforeClass
public static void setUpBeforeClass() throws Exception
{
//
// set up a simple database connection (e.g. DB2SimpleDataSource)
//
DataSource dbds = connect("localhost", "dbname", "userid", "password", 50000);
//
// now set up mock for the datasource to use the above connection
//
Context context = EasyMock.createNiceMock(Context.class);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, CEXInitialContextFactory.class.getName());
CEXInitialContextFactory.setCurrentContext(context);
try {
expect(context.lookup(ref)).andReturn(dbds).anyTimes();
replay(context);
} catch (NamingException e1) {
e1.printStackTrace();
}
//
// mock the close()
//
Connection conn = EasyMock.createNiceMock(Connection.class);
try {
conn.close();
expectLastCall().andAnswer(new IAnswer<Object>() {
public Object answer() {
System.out.println("Close connection");
return null;
}
});
replay(conn);
} catch (Exception e1) {
e1.printStackTrace();
}
}
@Test
public void testMakeRequest()
{
try {
Connection conn = getConnection();
ResultSet rset = conn.createStatement().executeQuery("SELECT COUNT(*) FROM SYSCAT.TABLES");
if(rset.next()) {
System.out.println("Count=" + rset.getString(1));
}
conn.close();
} catch (Exception ex) {
fail("Exception thrown, msg=" + ex.getMessage());
}
}
/**
* get a connection to the database
*
* Note: The ic.lookup is mocked and will return a database connection
*
* @return connection object
* @throws NamingException
* @throws SQLException
*/
private Connection getConnection() throws NamingException, SQLException
{
DataSource cloudexds = null;
try {
InitialContext ic = new InitialContext();
cloudexds = (DataSource) ic.lookup(ref);
} catch (NamingException e) {
e.printStackTrace();
}
return cloudexds.getConnection();
}
/**
* setup a connection to the database. This will be used with mock
*
* @param hostname
* @param dbname
* @param schema
* @param userid
* @param password
* @param port
* @return
*/
private static DataSource connect(String hostname, String dbname, String userid, String password, Integer port)
{
DB2SimpleDataSource dbds = new DB2SimpleDataSource();
//
// local 'docker' database
//
dbds.setDatabaseName(dbname);
dbds.setUser(userid);
dbds.setPassword(password);
dbds.setServerName(hostname);
dbds.setPortNumber(port);
dbds.setDriverType(4);
try {
dbds.getConnection();
} catch (Exception ex) {
fail("Cannot connect to the " + dbname + " database, msg=" + ex.getMessage());
}
return dbds;
}
}
I'm using EasyMock 3.3.
Appreciate any suggestions.