JNDI kontext bez aplikačního serveru?

V praxi jsem se setkal se situaci, kdy potřebuji spouštět unit testy mimo aplikační server. Na tom není nic zvláštního, dělá to každý. Pro testy si vytvořím vlastní konfigurace, které JNDI nepotřebují a je to. Jenže to by nebylo dostatečně zajímavé a hlavně je nutné udržovat dvě konfigurace, což je při vrozené lenosti programátora prostor pro inovaci.

Představme si situaci, kdy používáme databázi, která je konfigurována přímo v aplikačním serveru pomocí JNDI. Ve Springu ji pak používáme nějak takto:

 

Jak pak v unit testech toto vyřešit? Ideální by bylo, vytvořit si nějakým způsobem vlastní JNDI kontext, který pak bude naše aplikace využívat. Spring nám k tomu nabízí rozumné prostředky. Pojďme se tedy podívat, jak na to.

/**
 * InitialContext factory for test purposes - it simulates JNDI context.
 */
public class TestInitialContextFactory implements InitialContextFactory {
    /**
     * Creates an Initial Context for beginning name resolution.
     * Special requirements of this context are supplied
     * using environment.
     *

     * The environment parameter is owned by the caller.
     * The implementation will not modify the object or keep a reference
     * to it, although it may keep a reference to a clone or copy.
     *
     * @param environment The possibly null environment
     *                    specifying information to be used in the creation
     *                    of the initial context.
     * @return A non-null initial context object that implements the Context
     *         interface.
     * @throws javax.naming.NamingException If cannot create an initial context.
     */
    public Context getInitialContext(Hashtable environment) throws NamingException {

        // Vytvorime si datasource, ktery chceme publikovat v JNDI
        DriverManagerDataSource ds = new DriverManagerDataSource(
                "oracle.jdbc.driver.OracleDriver",
                "jdbc:oracle:thin:@localhost:1521:TES_DB",
                "test",
                "password");

        try {
            // Tady zacneme tvorit vlastni kontext
            SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();

            // Pridame nas datasource do kontextu
            builder.bind("jdbc/MyDataSource", ds);

            builder.activate();
            return builder.createInitialContextFactory(null).getInitialContext(null);
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Nyní už jen zbývá si v aplikaci nastavit, jak se má kontext vytvářet. To zajistíme konfigurací v souboru jndi.properties:

java.naming.factory.initial=eu.kratochvil.blog.ukazky.TestInitialContextFactory

Jak tuto problematiku řešíte na svých projektech? Budu rád, když mi odpovíte prostřednictvím komentáře.

2 odpovědi na “JNDI kontext bez aplikačního serveru?”

  1. V nasem testovacim prostredi neni toto aplikovatelne, ale je to kazdopadne zajimave :).
    Mame integracni testy rozhazene na spoustu masin s ruznymi kombinacemi OS/AS/JDK a jejich verzi a konfigurace databazi mame tak nejak generic 😉

  2. jenze to jsou integracni testy (FAT/iFAT) – ja mluvil/psal jsem o unit testech. To je IMHO rozdil.

Napsat komentář