How to test a DAO (using Spring and JPA) out of a container?

Asked

Viewed 975 times

1

I am developing an application with JPA 2, Spring and JSF 2 running in Wildfly 8.0.0. I have developed some previous applications following this same specification but never tested properly using junit. Now, I’d like to change that and test out more.

As I am very early in development and already want to test the application, came the first problem. How to test my application with it running out of a container? I say this because the datasource of my application is managed by the container. Therefore, being out of it I do not have a datasource.

I thought of assigning the responsibility of managing the datasource for Spring when I am running tests, but this implies new configuration files when I am running tests. More configuration files means more future maintenance. I would like to avoid this scenario, but if there is no other way...

Concluding and leaving the question, is there any way to test the application unitarily outside of a container with respect to datasource access?

EDIT: Adding some information that may be required for the answer:

My datasource (minhaapp-ds.xml):

<?xml version="1.0" encoding="UTF-8"?>
<datasources xmlns="http://www.jboss.org/ironjacamar/schema">
    <datasource jta="false" jndi-name="java:/datasource/minhaappds" pool-name="minhaAppDS" enabled="true" use-ccm="false">
        <connection-url>jdbc:oracle:thin:@etc:0000</connection-url>
        <driver-class>oracle.jdbc.OracleDriver</driver-class>
        <driver>ojdbc6.jar</driver>
        <pool>
            <min-pool-size>1</min-pool-size>
            <max-pool-size>15</max-pool-size>
        </pool>
        <security>
            <user-name>minha_app</user-name>
            <password>minha_app</password>
        </security>
        <validation>
            <validate-on-match>false</validate-on-match>
            <background-validation>false</background-validation>
        </validation>
        <timeout>
            <idle-timeout-minutes>5</idle-timeout-minutes>
        </timeout>
        <statement>
            <share-prepared-statements>false</share-prepared-statements>
        </statement>
    </datasource>
</datasources>

Man persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_1.xsd">

    <persistence-unit name="minhaAppPU" transaction-type="JTA">
        <jta-data-source>java:/datasource/minhaappds</jta-data-source>

        <class>br.com.cpy.model.Classe1</class>
        <class>br.com.cpy.model.Classe2</class>
        <class>br.com.cpy.model.Classe3</class>

        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/minhaappEMF" />
        </properties>
    </persistence-unit>
</persistence>

And finally, the spring-persistence-context.xml

<jee:jndi-lookup jndi-name="java:jboss/minhaappEMF" id="entityManagerFactory" expected-type="javax.persistence.EntityManagerFactory" />
<tx:jta-transaction-manager />
<tx:annotation-driven />

1 answer

3

The only way to do this is to make a JNDI MOCK, as it was posted on Oracle’s Randy Carver Blog.

 @BeforeClass
public static void setUpClass() 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:/datasource");

        // 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:/datasource/minhaappds", ds);
    } catch (NamingException ex) {
        Logger.getLogger(MyDAOTest.class.getName()).log(Level.SEVERE, null, ex);
    }

You can read his explanation better in, https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit

Another important point is the concept of unit testing. This is addressed very well in a response on unit testing with EJB, is a valid reading. https://stackoverflow.com/a/6486902/2928776

  • Thanks for the answer, but I’m studying and thinking about testing using Arquillian. No mocking and testing right in the container. http://arquillian.org/guides/getting_started/? utm_source=Cta

Browser other questions tagged

You are not signed in. Login or sign up in order to post.