Я пытаюсь запустить тесты JUnit на основе "рабочих" классов базы данных, которые ищут jndi на InitialContext
, чтобы получить DataSource
. Рабочие классы обычно запускаются на сервере приложений Glassfish v3, который имеет соответствующие ресурсы jdbc.
Код работает очень хорошо при развертывании на сервере приложений, но не запускается из среды тестирования JUnit, потому что, очевидно, он не может найти ресурсы jndi. Поэтому я попытался настроить InitialContext в тестовом классе, который привязывает источник данных к соответствующему контексту, но он не работает.
Вот код, который у меня есть в тесте
@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);
}
}
Затем класс DataWorker
имеет метод со следующим кодом, более или менее
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
}
Если я изменю
ic.createSubContext("java:/comp/env/jdbc");
ic.bind("java:/comp/env/jdbc/TestDS",testDS)
;
линии в ic.createSubContext("jdbc");
ic.bind("jdbc/TestDS",testDS);
Рабочий класс может найти DataSource, но не дает ошибки, говоря, что "username не удалось войти в систему на сервере".
Если я передам DataSource, который я создаю в методе JUnit, непосредственно в рабочий, он может подключаться и запускать запросы.
Итак, я хотел бы знать, как связать DataSource, который может быть просмотрен рабочим классом, не находясь в веб-контейнере.