Context context = new InitialContext();
dataSource = (DataSource) context.lookup("Java:comp/env/jdbc/multiDS");
connection = dataSource.getConnection();
上記のコードをあざけるのを手伝ってください。
こんにちはトムアンダーソン
以下のコードを試しました
@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();
}
}
しかし、次のようなエラーが発生します。
com.hp.corona.common.exception.CacheException: org.Apache.naming.NamingContext cannot be cast to javax.sql.DataSource
必要なコードをテストするのを手伝ってくださいconnection JNDIデータソースから
ここで行うべき正統的なことは、Context
が(依存性注入フレームワークによって、または手動で)そこに注入されるようにコードを変更することです。次に、単体テストのモックを渡すだけです。
これを行うことができず、コードでIntialContext
自体を作成する必要がある場合は、モックを挿入できる偽のJNDI実装を設定する必要があります。 Webで インメモリJNDI実装 または モックJNDI実装 を検索すると、さまざまなオプションが見つかりますが、自分で作成することもできます。基本的には、適切なモックを単に返すInitialContextFactory
の実装が必要です。これは、Java.naming.factory.initial
システムプロパティを設定して選択します。
必要なクラスを書くときにひび割れがありました。どうぞ:
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();
}
}
};
}
}
次のように使用します。
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
}
}
Spring実装を使用できます。これは次のように機能します。
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
[...]
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
builder.bind("jdbc/myDataSource", myDS);
builder.activate();
これはSimple-JNDIで簡単に実行できます。作業ディレクトリにプロパティファイル「jdbc/multiDS.properties」を作成して、次のプロパティでデータソースを設定します。
type=javax.sql.DataSource
driver=org.gjt.mm.mysql.Driver
url=jdbc:mysql://localhost/testdb
user=testuser
password=testing
次に、コンテキストをインスタンス化します
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);
その後、あなたは呼び出すことができます
dataSource = (DataSource) context.lookup("Java:comp/env/jdbc/multiDS");
Simple-JNDIについての詳細はこちら https://github.com/h-thurow/Simple-JNDI