2013-12-17 8 views
5

My Java EE 7 aplikacja, która wykorzystuje Spring, działa na Tomcat 7. uzyskuje dostęp do bazy danych za pomocą JNDI źródła danych, zdefiniowany przez tę linię w context.xml:Czy mogę uniknąć przedefiniowania źródła danych JNDI podczas korzystania z JUnit?

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

stworzyłem kilka testów JUnit. Kiedy próbowałem je uruchomić (w Eclipse, klikając prawym przyciskiem myszy i wybierając klasę testową Run as | JUnit Test), wyjątek wystąpił:

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 
... 

Dzięki tym pomocny post - https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit - Znalazłem rozwiązanie. Dodałem to do mojej klasy testowej:

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

Ale to jest ohydne! Jestem zmuszony do dwukrotnego zdefiniowania źródła danych, raz w context.xml i ponownie w mojej klasie testowej. I jestem zmuszony przechowywać moje hasło do bazy danych w kodzie Java, które będzie sprawdzane w kontroli kodu źródłowego.

Ja już konsultowany ten post, a także: Setting up JNDI Datasource in jUnit

Czy istnieje lepszy sposób?

+0

z przyjemnością odpowie na to pytanie – chrismarx

Odpowiedz

0

Powód jest taki, że twój test nie działa wewnątrz tomcat, ale działa w oddzielnym egzemplarzu JVM.

Spróbuj zbudować swój test jednostkowy używając Arquillian - to narzędzie zapakuje twój test jako prosta aplikacja internetowa, która jest wykonywana w twoim tomcat. Powoduje to, że wszystko, co jest dostępne w tomcat, będzie dostępne w twoich testach, w tym zasobach.

0

Można również użyć TomcatJNDI. Czyta pliki konfiguracyjne Tomcat i tworzy środowisko JNDI, jak w twojej aplikacji internetowej. To jest tak proste jak ten przykład kodu:

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

Teraz możesz uzyskać dostęp do wszystkich swoich zasobów zadeklarowanych w plikach konfiguracyjnych Tomcat.

Find out more about it here.

Powiązane problemy