Estoy tratando de ejecutar pruebas JUnit en clases de base de datos de "trabajador" que hacen una búsqueda jndi en un InitialContext
para obtener un DataSource
. Las clases de trabajadores generalmente se ejecutan en un servidor de aplicaciones de Glassfish v3 que tiene definidos los recursos jdbc adecuados.¿Cómo puedo vincular un DataSource a un InitialContext para la prueba de JUnit?
El código funciona bien cuando se implementa en el servidor de aplicaciones, pero no se ejecuta desde el entorno de prueba JUnit, porque obviamente no puede encontrar los recursos jndi. Así que traté de configurar un InitialContext en la clase de prueba que vincula un origen de datos al contexto apropiado, pero no funciona.
Aquí está el código que tengo en la prueba
@BeforeClass
public static void setUpClass() throws Exception {
try {
// Create initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES,
"org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:/comp");
ic.createSubcontext("java:/comp/env");
ic.createSubcontext("java:/comp/env/jdbc");
// Construct DataSource
SQLServerConnectionPoolDataSource testDS = new SQLServerConnectionPoolDataSource();
testDS.setServerName("sqlserveraddress");
testDS.setPortNumber(1433);
testDS.setDatabaseName("dbname");
testDS.setUser("username");
testDS.setPassword("password");
ic.bind("java:/comp/env/jdbc/TestDS", testDS);
DataWorker dw = DataWorker.getInstance();
} catch (NamingException ex) {
Logger.getLogger(TitleTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
Entonces la clase DataWorker
tiene un método con el siguiente código, más o menos
InitialContext ic = null;
DataSource ds = null;
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
String sql = "SELECT column FROM table";
try{
ic = new InitialContext();
ds = (DataSource) ic.lookup("jdbc/TestDS");
c = ds.getConnection();
ps = c.prepareStatement(sql);
// Setup the Prepared Statement
rs = ps.executeQuery();
if(rs.next){
//Process Results
}
}catch(NamingException e){
throw new RuntimeException(e);
}finally{
//Close the ResultSet, PreparedStatement, Connection, InitialContext
}
Si cambio la
ic.createSubContext("java:/comp/env/jdbc");
ic.bind("java:/comp/env/jdbc/TestDS",testDS)
;
líneas a
ic.createSubContext("jdbc");
ic.bind("jdbc/TestDS",testDS);
La clase trabajadora es capaz de encontrar el origen de datos, pero no da un error que dice que "username al iniciar sesión en el servidor".
Si paso el DataSource que creo en el método JUnit directamente al trabajador, puede conectarse y ejecutar consultas.
Por lo tanto, me gustaría saber cómo enlazar un DataSource que puede ser buscado por la clase de trabajador sin estar en el contenedor web.