2013-06-13 9 views
11
Context context = new InitialContext(); 
dataSource = (DataSource) context.lookup("java:comp/env/jdbc/multiDS"); 
connection = dataSource.getConnection(); 

Proszę, pomóż mi kpić z powyższego kodu.Junit Testowanie początkowego kontekstu JNDI poza serwerem aplikacji

Cześć Tom Anderson

Próbowałem poniższy kod

@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");    
      Context ic = new InitialContext(); 

      ic.createSubcontext("java:"); 
      ic.createSubcontext("java:comp"); 
      ic.createSubcontext("java:comp/env"); 
      ic.createSubcontext("java:comp/env/jdbc"); 
      ic.createSubcontext("java:comp/env/jdbc/multiDS"); 
      // Construct DataSource 
      OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource(); 
      ds.setURL("jdbc:oracle:thin:@g9u0696.houston.hp.com:1525:CRNAD"); 
      ds.setUser("uname"); 
      ds.setPassword("pwd"); 
     } catch (NamingException ex) { 
      ex.printStackTrace(); 
     } 
} 

ale jego dając błąd jako:

com.hp.corona.common.exception.CacheException: org.apache.naming.NamingContext cannot be cast to javax.sql.DataSource 

Proszę mi pomóc, aby przetestować kod chcę tylko połączenia z Źródło danych JNDI

+0

to naprawdę zależy od serwera aplikacji. w dowolny sposób obejrzyj ten http://www.codeproject.com/Articles/25741/EJB-3-0-Remote-Session-Bean-Lookup – fGo

Odpowiedz

18

o Prawą rzeczą, którą należy tu zrobić, jest zmiana kodu użytkownika, aby wprowadzić do niego Context (przez szkielet wtrysku zależności lub ręcznie). Następnie po prostu przejdziecie w symulację w teście jednostki.

Jeśli nie możesz tego zrobić, a Twój kod musi sam utworzyć IntialContext, musisz skonfigurować fałszywą implementację JNDI, do której możesz wstrzykiwać makiety. Jeśli przeszukujesz sieć pod kątem in-memory JNDI implementation lub mock JNDI implementation, znajdziesz różne opcje lub możesz sam je napisać. Zasadniczo potrzebna jest implementacja InitialContextFactory, która po prostu zwraca odpowiednią próbę, którą następnie wybierasz, ustawiając właściwość systemową java.naming.factory.initial.

Miałem pęknięcie w pisaniu niezbędnych klas. Proszę bardzo:

public class MockInitialContextFactory implements InitialContextFactory { 

    private static final ThreadLocal<Context> currentContext = new ThreadLocal<Context>(); 

    @Override 
    public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException { 
     return currentContext.get(); 
    } 

    public static void setCurrentContext(Context context) { 
     currentContext.set(context); 
    } 

    public static void clearCurrentContext() { 
     currentContext.remove(); 
    } 

} 

public class MockInitialContextRule implements TestRule { 

    private final Context context; 

    public MockInitialContextRule(Context context) { 
     this.context = context; 
    } 

    @Override 
    public Statement apply(final Statement base, Description description) { 
     return new Statement() { 
      @Override 
      public void evaluate() throws Throwable { 
       System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName()); 
       MockInitialContextFactory.setCurrentContext(context); 
       try { 
        base.evaluate(); 
       } finally { 
        System.clearProperty(Context.INITIAL_CONTEXT_FACTORY); 
        MockInitialContextFactory.clearCurrentContext(); 
       } 
      } 
     }; 
    } 
} 

Zastosowanie następująco:

public class FooTest { 

    private final Context context = mock(Context.class); 

    @Rule 
    public MockInitialContextRule mockInitialContextRule = new MockInitialContextRule(context); 

    @Test 
    public void testName() throws Exception { 
     // set up stubbings on the context mock 
     // invoke the code under test 
    } 
} 
+0

Cześć Mr Tom Anderson .. próbowałem poniższy kod – ravichandra

+0

Witam Mr Anderson .. Właśnie edytowałem kod testowy proszę dać mi sugestię – ravichandra

+0

Twój kod jest nieprawidłowy. Porównaj to z oryginalnym kodem Randy'ego Carvera: https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit. Robisz 'createSubcontext', kiedy powinieneś robić' bind'. Komunikat o wyjątku jest na to wskazówką - utworzyłeś 'NamingContext', w którym powinieneś stworzyć' DataSource'. –

3

Można użyć realizację wiosna, to działa tak:

import org.springframework.mock.jndi.SimpleNamingContextBuilder; 

[...] 

SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); 
builder.bind("jdbc/myDataSource", myDS); 
builder.activate(); 
1

Można to łatwo zrobić z proste JNDI. Utwórz plik Property „JDBC/multiDS.properties” w swoim katalogu roboczym do skonfigurowania źródła danych z tych właściwości:

type=javax.sql.DataSource 
driver=org.gjt.mm.mysql.Driver 
url=jdbc:mysql://localhost/testdb 
user=testuser 
password=testing 

Następnie instancji kontekstu z

final Hashtable<String, String> env = new Hashtable<String, String>(); 
env.put("org.osjava.sj.root", "working_dir"); 
env.put("org.osjava.sj.jndi.shared", "true"); 
env.put("java.naming.factory.initial", "org.osjava.sj.SimpleContextFactory"); 
env.put("org.osjava.sj.delimiter", "/"); 
env.put("org.osjava.sj.space", "java:comp/env") 
Context ctx = new InitialContext(env); 

po tym można nazwać

dataSource = (DataSource) context.lookup("java:comp/env/jdbc/multiDS"); 

Znajdź więcej informacji o Simple-JNDI tutaj https://github.com/h-thurow/Simple-JNDI

Powiązane problemy