Настройка источника данных JNDI в jUnit


Я пытаюсь настроить тестирование jUnit. Наша база данных подключена к серверу с помощью JNDI. У нас есть xml, описывающий установку в корне.XML. Как настроить jUnit для подключения к базе данных? Я бы предпочел, чтобы он просто прочитал материал с корня.xml, но я открыт для настройки его в любом случае, что работает.

6 13

6 ответов:

Я нашел этот блог: https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit

Об Источнике Данных H2: http://www.h2database.com/javadoc/org/h2/jdbcx/JdbcConnectionPool.html

Итак, для моего кода:

package com.example.test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.h2.jdbcx.JdbcConnectionPool;

import junit.framework.TestCase;

public class JunitDataSource extends TestCase {

    public void setUp() throws Exception {
        // rcarver - setup the jndi context and the datasource
        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");

            JdbcConnectionPool ds = JdbcConnectionPool.create(
                    "jdbc:h2:file:src/main/resources/test.db;FILE_LOCK=NO;MVCC=TRUE;DB_CLOSE_ON_EXIT=TRUE", "sa", "sasasa");
            // Construct DataSource
            // OracleConnectionPoolDataSource ds = new
            // OracleConnectionPoolDataSource();
            // ds.setURL("jdbc:oracle:thin:@host:port:db");
            // ds.setUser("MY_USER_NAME");
            // ds.setPassword("MY_USER_PASSWORD");

            ic.bind("java:/mydatasourcename", ds);
        } catch (NamingException ex) {
            Logger.getLogger(JunitDataSource.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void testSimple() throws Exception {

        // Obtain our environment naming context
        Context initCtx = new InitialContext();

        // Look up our datasource
        DataSource ds = (DataSource) initCtx.lookup("java:/mydatasourcename");

        Connection conn = ds.getConnection();
        Statement stmt = conn.createStatement();

        ResultSet rset = stmt.executeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");


        while (rset.next()) {
          System.out.println("<<<\t"+rset.getString("TABLE_NAME"));
        }


    }

}

Примечание : мне пришлось добавить библиотеку Tomcat и банки внутри каталога tomcat's bin, чтобы заставить его работать

Я обнаружил, что лучший способ сделать это-использовать нечто под названием Simple-Jndi.

Я добавил Это в файл maven:

    <dependency>
        <groupId>simple-jndi</groupId>
        <artifactId>simple-jndi</artifactId>
        <version>0.11.4.1</version>
        <scope>test</scope>
    </dependency>

Вы можете скачать пакет здесь, загрузка содержит инструкцию по эксплуатации. http://code.google.com/p/osjava/downloads/detail?name=simple-jndi-0.11.4.1.zip&can=2&q=

После добавления в свой проект вам просто нужно добавить пару файлов свойств, в соответствии с инструкциями.

Однако после добавления зависимость, я считаю, что вы можете добавить свои ресурсы jndi программно вместо использования файлов свойств. Вы делаете что-то вроде этого: (new InitialContext()).rebind ("datasource", myDatasource);

Я уже много лет использую Simple-JNDI для этой цели. Он предоставляет вам реализацию службы JNDI в памяти и позволяет заполнять среду JNDI объектами, определенными в файлах свойств. Существует также поддержка загрузки источников данных или пулов соединений, настроенных в файле.

Чтобы получить пул соединений, вам нужно создать файл, подобный этому:

type=javax.sql.DataSource
driver=com.sybase.jdbc3.jdbc.SybDriver
pool=myDataSource
url=jdbc:sybase:Tds:servername:5000
user=user
password=password 

В вашем приложении вы можете получить доступ к пулу через

Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("path/to/your/connectionPool");

Вы можете найти больше об этом на https://github.com/h-thurow/Simple-JNDI .

TomcatJNDI помогает и в этой ситуации. Он может обрабатывать конфигурационные файлы Tomcat и создавать ту же среду JNDI, что и Tomcat, но без запуска сервера. Таким образом, вы можете запускать классы с зависимостями от среды Tomcat JNDI, например, в тестах JUnit.

TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processContextXml(new File(“tomcat-root-dir/conf/context.xml”);
tomcatJNDI.start();

Тогда ваши классы могут искать источник данных, как если бы они работали в Tomcat.

Подробнее о TomcatJNDI можно узнать здесь: https://github.com/h-thurow/TomcatJNDI

Вы хотите создать источник данных программно на сервере приложений? Referene:

  1. создать источник данных JBoss 7 из программы
  2. создайте источник данных Weblogic из программы

Если вы уже создали на Sever,

public class YourTestCase {
    private java.sql.Connection conn;

    @BeforeClass
    public static void init() {
        /* Weblogic */
        try {
            Context ctx = null;
            Hashtable ht = new Hashtable();
            ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
            ht.put(Context.PROVIDER_URL, "t3://<your-host>:<your:post>");
            ctx = new InitialContext(ht);
            javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup ("<your-datasource-jndi-name>");
            conn = ds.getConnection();
        } catch(Exception e) {

        }
        /* JBoss 5*/
        Context.INITIAL_CONTEXT_FACTORY ---> org.jnp.interfaces.NamingContextFactory
        Context.PROVIDER_URL ---->http://localhost:1099
    }
    @AfterClass
    public static void finished() {
    }


    @Test
    public void testMethod() {
        try {
            Statement stmt = conn.createStatement();
            stmt.execute("select * from someTable");
            ResultSet rs = stmt.getResultSet();  
                // do operation
            stmt.close();
            conn.close();
            } catch (Exception e) {
                // a failure occurred
            } finally {
                try {ctx.close();
                } catch (Exception e) {
                }
            }
        }
    }
}

Вы можете добавить Tomcat lib через Maven dependence, используя ниже, чтобы заставить его работать.

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>catalina</artifactId>
    <version>6.0.18</version>
    <scope>test</scope>
</dependency>

Я думаю, что вы должны попробовать издеваться над базой данных. Используйте соответствующий фреймворк, например Mockito, он создает mocks и обладает DI способностями.