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

Vui lòng giúp tôi thử mã trên.Kiểm tra Junit JNDI InitialContext bên ngoài máy chủ ứng dụng

Hi Tom Anderson

Tôi đã thử đoạn code dưới đây

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

Nhưng lỗi cho nó như:

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

Xin hãy giúp tôi để kiểm tra mã tôi chỉ muốn kết nối từ Nguồn dữ liệu JNDI

+0

nó thực sự phụ thuộc vào máy chủ ứng dụng của bạn. bất kỳ cách nào hãy xem http://www.codeproject.com/Articles/25741/EJB-3-0-Remote-Session-Bean-Lookup – fGo

Trả lời

18

o Điều rthodox để làm ở đây sẽ là thay đổi mã của bạn để Context được tiêm vào nó (bởi một khuôn khổ tiêm phụ thuộc, hoặc bằng tay). Sau đó, bạn chỉ cần vượt qua trong một thử nghiệm trong bài kiểm tra đơn vị của bạn.

Nếu bạn không thể làm điều này, và mã của bạn phải tự tạo IntialContext, thì bạn sẽ cần phải thiết lập triển khai JNDI giả để bạn có thể tiêm mocks. Nếu bạn tìm kiếm trên web cho in-memory JNDI implementation hoặc mock JNDI implementation, bạn sẽ tìm thấy các tùy chọn khác nhau hoặc bạn có thể tự mình viết. Về cơ bản, bạn sẽ cần thực hiện InitialContextFactory chỉ đơn giản trả về một mô hình phù hợp, sau đó bạn chọn bằng cách đặt thuộc tính hệ thống java.naming.factory.initial.

Tôi đã có lỗi khi viết các lớp cần thiết. Ở đây bạn đi:

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

Sử dụng như sau:

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

Xin chào ông Tom Anderson .. tôi đã thử mã dưới đây – ravichandra

+0

Xin chào ông Anderson .. i Chỉ cần chỉnh sửa mã kiểm tra xin vui lòng cho tôi gợi ý – ravichandra

+0

Mã của bạn không đúng. So sánh nó với mã ban đầu của Randy Carver: https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit. Bạn đang làm một 'createSubcontext' khi bạn nên làm một' bind'. Thông báo ngoại lệ gợi ý rằng bạn đã tạo một 'NamingContext', nơi bạn nên tạo một' DataSource'. –

3

Bạn có thể sử dụng việc thực hiện mùa xuân, nó hoạt động như thế này:

import org.springframework.mock.jndi.SimpleNamingContextBuilder; 

[...] 

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

này có thể dễ dàng thực hiện với Simple-JNDI. Tạo một tập tin bất động sản "jdbc/multiDS.properties" trong thư mục làm việc của bạn để cấu hình nguồn dữ liệu của bạn với các thuộc tính:

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

Sau đó nhanh chóng các bối cảnh với

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

Sau đó bạn có thể gọi

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

Tìm thêm thông tin về Simple-JNDI tại đây https://github.com/h-thurow/Simple-JNDI

Các vấn đề liên quan