Можно ли избежать переопределения источника данных JNDI при использовании JUnit?

Мое приложение Java EE 7, использующее Spring, работает на Tomcat 7. Оно обращается к базе данных с помощью источника данных JNDI, определенного этой строкой в ​​context.xml:

<Resource auth="Container" driverClassName="org.postgresql.Driver" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/leadmanager" password="xxxxxxxx" type="javax.sql.DataSource" url="jdbc:postgresql://localhost:5432/leadmanager" username="postgres"/>

Я создал несколько тестов JUnit. Когда я попытался запустить их (в Eclipse, щелкнув правой кнопкой мыши тестовый класс и выбрав Run As | JUnit Test), возникло исключение:

javax.persistence.PersistenceException: [PersistenceUnit: leadmanager] Unable to build EntityManagerFactory
...
Caused by: org.hibernate.service.jndi.JndiException: Error parsing JNDI name [java:/comp/env/jdbc/leadmanager]
...
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
...

Спасибо за этот полезный пост -- https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit -- Я нашел решение. Я добавил это в свой тестовый класс:

@BeforeClass
public static void setUpClass() throws Exception {

    // 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");

    PGPoolingDataSource ds = new PGPoolingDataSource();
    ds.setServerName("localhost:5432/leadmanager");
    ds.setUser("postgres");
    ds.setPassword("xxxxxxxx");
    ic.bind("java:/comp/env/jdbc/leadmanager", ds);
}

Но это ужасно! Мне приходится определять источник данных дважды, один раз в context.xml и еще раз в моем тестовом классе. И я вынужден хранить свой пароль базы данных в коде Java, который будет проверен в системе управления версиями.

Я уже ознакомился с этим сообщением: Настройка источника данных JNDI в jUnit

Есть ли способ лучше?


person Steve Saporta    schedule 17.12.2013    source источник
comment
хотелось бы получить ответ на этот вопрос   -  person chrismarx    schedule 14.04.2015


Ответы (2)


Причина в том, что ваш тест выполняется не внутри tomcat, а в отдельном экземпляре JVM.

Попробуйте создать свой модульный тест, используя Arquillian — этот инструмент упакует ваш тест как простое веб-приложение, которое выполняется в вашем tomcat. В результате все, что доступно в tomcat, будет доступно и в ваших тестах, включая ресурсы.

person OndroMih    schedule 02.11.2015

Вы также можете использовать TomcatJNDI. Он читает файлы конфигурации Tomcat и создает среду JNDI, как в вашем веб-приложении. Это так же просто, как этот пример кода:

TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.start();

Теперь вы можете получить доступ ко всем вашим ресурсам, которые вы объявили в файлах конфигурации Tomcat.

Подробнее об этом здесь.

person Holger Thurow    schedule 28.10.2017