barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

вторник, 20 марта 2012 г.

Инициализация InitialContext`а и stubbing пула JDBC-соединений при unit-тестировании веб-приложения за пределами контейнера

Проблема:

В приложении используются объекты, получаемые из InitialContext`а, которые помещаются туда контейнером сервлетов. Конкретно, используется пул соединений с БД, инициализируемый в context.xml веб-приложения для Tomcat следующим образом:
<Context antiJARLocking="true" path="/SMEVMonitoring">
  <Resource name="jdbc/myDb" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="1" maxWait="10000"
               username="postgres" password="postgres" driverClassName="org.postgresql.Driver"
               url="jdbc:postgresql://postgreshost:5432/myDb"/>
</Context>
Используется пул следующим образом:
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource dataSource = (DataSource)envContext.lookup("jdbc/myDb");
jdbcConn = dataSource.getConnection();
При проведении unit-теста в IDE, естественно, по адресу "java:/comp/env/jdbc/myDb", ничего не оказывается, т.к. DataSource создается Tomcat`ом. Более того, оказывается неустановленным системное свойство "java.naming.factory.initial", поэтому контекст вообще не может инициализироваться.

Решение:

Перед запуском теста (например, в методе, помеченном @BeforeClass в JUnit) необходимо выполнить настройку InitialContext`а и положить в него необходимые объекты (в моем случае - DataSource, который, вместо пула, я заменил BasicDataSource`ом):
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUrl("jdbc:postgresql://postgreshost:5432/myDb");
ds.setUsername("postgres");
ds.setPassword("postgres");
// Configure and populate initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES,        "org.apache.naming");    
Context initContext = new InitialContext();
initContext.createSubcontext("java:");
initContext.createSubcontext("java:/comp");
initContext.createSubcontext("java:/comp/env");
initContext.createSubcontext("java:/comp/env/jdbc");
initContext.bind("java:/comp/env/jdbc/myDb",ds);
Для компиляции и выполнения тестов потребуется, чтобы к проекту были подключены библиотеки Tomcat`а (т.к. используется org.apache.naming.java.javaURLContextFactory).

Комментариев нет:

Отправить комментарий