Setting up JNDI Datasource in jUnit

2019-01-11 07:34发布

I am trying to set up some jUnit testing. Our database is connected by the server using JNDI. We have an xml describing the setup in root.xml. How do I set up jUnit to hook up to the database? I'd prefer to have it just read the the stuff off of root.xml, but I'm open to setting it up anyway that works.

标签: java junit jndi
6条回答
ら.Afraid
2楼-- · 2019-01-11 07:48

I think you should try to mock out the database. Use appropriate framework, for example Mockito, it creates mocks and have DI abilities.

查看更多
闹够了就滚
3楼-- · 2019-01-11 07:49

You can add Tomcat lib via maven dependency using below, to get it working.

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>catalina</artifactId>
    <version>6.0.18</version>
    <scope>test</scope>
</dependency>
查看更多
相关推荐>>
4楼-- · 2019-01-11 07:59

I have used Simple-JNDI for this purpose for years now. It gives you an in-memory implementation of a JNDI Service and allows you to populate the JNDI environment with objects defined in property files. There is also support for loading datasources or connection pools configured in a file.

To get a connection pool you have to create a file like this:

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

In your application you can access the pool via

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

You can find more about it at https://github.com/h-thurow/Simple-JNDI.

TomcatJNDI helps with that situation too. It can process Tomcat’s configuration files and creates the same JNDI environment as Tomcat does, but without starting a server. So you can run classes with dependencies on Tomcat’s JNDI environment in e. g. JUnit tests.

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

Then your classes can lookup the DataSource as when they would run in Tomcat.

More about TomcatJNDI can be found here: https://github.com/h-thurow/TomcatJNDI

查看更多
该账号已被封号
5楼-- · 2019-01-11 08:00

I found that the best way to do it is to use something called Simple-Jndi.

I added this to the maven file:

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

You can download the the package here, the download contains an instruction manual. http://code.google.com/p/osjava/downloads/detail?name=simple-jndi-0.11.4.1.zip&can=2&q=

After adding to to your project you just have to add a couple of properties files, per the instructions.

However, after you add the dependency, I believe you can add your jndi resources programmatically instead of using properties files. You do something like this: (new InitialContext()).rebind("datasource",myDatasource);

查看更多
男人必须洒脱
6楼-- · 2019-01-11 08:10

Would you like to create datasource programmatically on Application Server? Referene :

  1. Create Datasource JBoss 7 from program
  2. Create Datasource Weblogic from program

If you already created on 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) {
                }
            }
        }
    }
}
查看更多
霸刀☆藐视天下
7楼-- · 2019-01-11 08:11

I've found this Blog: https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit

About H2 Datasource: http://www.h2database.com/javadoc/org/h2/jdbcx/JdbcConnectionPool.html

So for my Code:

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


    }

}

Note: I had to add Tomcat Library and the jars inside the Tomcat's bin directory to get it working

查看更多
登录 后发表回答