JNDIからリソースを引っ張ってくるコードのテストが書きたい
JNDIからDataSourceなどのリソースを取得するコードをテストしたいとき、JNDIの実装を用意したくなります。
例えばこんなコードです。
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/mysql");
Connection con = ds.getConnection();
こういうコードをテストするときは当然ですけどコンテナなしで動かしたいです。
いろんな方法がある
調べてみるといろいろな方法があります。
例えば、TomcatのJNDI実装を使う方法とか、
http://d.hatena.ne.jp/yone098/20100330/1269929119
SimpleJNDI とかいう実装があったりとか、
http://code.google.com/p/osjava/wiki/SimpleJNDI
JNDI DataSource helper package とかいうDataSourcesのプロバイダがあったりとか、
https://www.coderanch.com/how-to/java/CodeBarnLibrariesAndFrameworks
そんな感じです。
mavenで引っ張れるのと、なんとなく名前に引かれて、私はSimpleJNDIをしばらく使っていましたが、プロパティーファイル用意したりとか、なんかいろいろシステムプロパティー設定しないといけなかったりとかちょっと大げさだなぁと思っていました。
なんかちょっと大げさ→車輪の再発明
というわけで僕がやりたいのは、
単純に
- テストケースの中で指定した名前に任意のオブジェクトがbindできて
- それがコード内でlookupできる
というだけなので、それだけができるMockなJNDIを作りました。
ライブラリ、というかサンプルです。
public class JUnitJndiTest {
@ClassRule
public static JndiRule jndi = new JndiRule() {
@Override
protected void bind(Context context) throws NamingException {
context.bind("someobj", new Object());
context.bind("somestring", "abc");
Context cx = context.createSubcontext("java:/comp/env");
cx.bind("jdbc/mysql", "MysqlDatasource");
}
};
@Test
public void lookup() throws NamingException {
assertThat(new InitialContext().lookup("someobj"), is(notNullValue(Object.class)));
assertThat((String)new InitialContext().lookup("somestring"), is("abc"));
}
}
ついでに、JUnit4から簡単に使えるようにExternalResourceにしてみました。
lookupとbindと、なんちゃって実装ではありますが、createSubContextが動きます。
他は動きません。
多分ソースコード中で、JNDI を lookupする場所ってそんなに多くないのでlookupの方法は限定できるでしょうし、Contextオブジェクトってそんなに複雑な使われ方はあんまりしないと思うんです。(気のせいでしょうか。
なので、lookupの仕方に合わせてbindしてあげることができれば、ほとんどOKなんじゃないかなぁと思っています。
JNDI使用するコードのテストで悩んだひとは、参考にしてもらえるとうれしいです。
JNDI使用するコードのテストで悩んだひとは、参考にしてもらえるとうれしいです。
コメント