Статьи

Создание ресурсов JNDI для тестирования JUnit с использованием Spring

До недавнего времени у меня были статические методы настройки моей базы данных в памяти (HSQLDB). Я вызвал эти методы в setUp / tearDown моих тестов JUnit. Это всегда казалось мне неестественным, так как я использую Spring, и все должно проходить через контекст приложения.

2016-04-22-JNDI-JUnit

Создание простого компонента JNDI

Поскольку я использую JNDI в производстве, мне также пришлось создать ресурс JNDI для моего приложения. Простой Spring Bean, использующий Apache Commons DBCP, делает свое дело:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class JndiBean {
 
    public JndiBean() {
        try {
            DriverAdapterCPDS cpds = new DriverAdapterCPDS();
            cpds.setDriver("org.hsqldb.jdbc.JDBCDriver");
            cpds.setUrl("jdbc:hsqldb:mem:testdb");
            cpds.setUser("SA");
            cpds.setPassword("");
 
            SharedPoolDataSource dataSource = new SharedPoolDataSource();
            dataSource.setConnectionPoolDataSource(cpds);
            dataSource.setMaxActive(10);
            dataSource.setMaxWait(50);
 
            SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
            builder.bind("java:comp/env/jdbc/timeandbill", dataSource);
            builder.activate();
        } catch (NamingException | ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
}

Вы не должны использовать эту базовую конфигурацию, не задумываясь, но она хорошо работает для модульного тестирования.

Сначала я создал адаптер драйвера, содержащий все, что мне нужно для подключения к моей базе данных. Это может быть MySQL, Postgres или что-то еще, что вы предпочитаете.

Затем я создаю источник SharedPoolDatasource. Нет необходимости поддерживать большое количество соединений, поскольку тесты обычно выполняются последовательно. Даже если это не так, контекст Spring обычно создается по крайней мере для каждого тестового класса. Маловероятно, что вы получаете выгоду от объединения, но я хотел придерживаться того, что обычно делают производственные серверы.

SimpleNamingContextBuilder — это то, что в конечном итоге связывает ранее созданный источник данных с контекстом JNDI. Как видите, это простая задача: просто связать ее, затем активировать, и все готово.

Добавление компонента JNDI в контекст

Следующий шаг — добавить это во второй файл applicationContext.xml, который загружается только тестами JUnit. Я нахожусь в моей папке Unit-tests и содержит:

1
<bean id="jndi" class="de.grobmeier.tab.webapp.JndiBean" lazy-init="false" />

Эти аннотации в моих тестах обеспечивают загрузку всех файлов applicationContext:

1
2
3
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:applicationContext.xml"})
public class TimeConverterTest {

Мое производственное приложение содержит текст:

1
2
3
4
5
6
7
8
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/timeandbill"/>
    <property name="resourceRef" value="true" />
</bean>
 
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
</bean>

Поскольку нет сервера Java EE, работающего на уровне JUnit. Вместо этого соединение JNDI было создано вручную. В производственной среде JUnits applicationContext не загружается, и контейнер Java EE предоставляет ресурс JNDI.

Примечание: я обнаружил, что Mybatis использует функцию «byType» от Springs.

Ссылка: Создайте ресурсы JNDI для тестирования JUnit с помощью Spring от нашего партнера по JCG Кристиана Гробмайера из блога PHP и Java Entwickler .