JPAを使うテストとクラスパスについて
上記のパーシステンス周りの実装をEclipse上でテストしようとすると、ちょっとコツがいりました。
もともと、テストとかも「activator ui」によるブラウザ上の開発環境で実行する前提で調整されているので
Eclipse環境はあまり優遇されていないようです。
そもそものPlayでのお作法も含めて、ざっくり言うと以下4点の対応が必要。
FakeApplicationを用意してあげる
Play上で動くコードはPlayが色々とお膳立てをしてくれているわけで、テストでも同じようにお膳立てをしてあげる必要があります。
これについてはネット上に色々情報がありますが、僕は以下のようなクラスを継承してテストを書きました。
public abstract class FakeApplicationTest { protected EntityManager em; FakeApplication app; @Before public void setUpTest() { this.app = fakeApplication(); Helpers.start(this.app); } @After public void tearDownTest() { Helpers.stop(this.app); } }
Transactionを用意してあげる
まあこれもおまじないみたいなもんです。
テストを書く際に、以下のように記述をしてあげます。
public class HogeTest extends FakeApplicationTest { @Test public void testHero() { JPA.withTransaction(new play.libs.F.Callback0() { public void invoke() { // テスト内容 } }); } }
scala-libraryにクラスパスを通す
これは多分、Play-Javaの実装上のちょっとした手落ちなんじゃないかと思うんですけどね。
上記の記述でactivator ui 上では問題なく動くのですが、eclipse上からFakeApplicationを動かそうとすると怒られます。
java.lang.NoClassDefFoundError: scala/collection/Map
at testutil.FakeApplicationTest.setUpTest(FakeApplicationTest.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
・・・・・
つまり、FakeApplicationを動かすにはScalaのMap実装が必要なんですね。
仕方ないので、eclipse上で「scala-library-2.11.x.jar」とかを Build Path に含めてあげます。
(まあ、activator eclipseやると元に戻ってしまうのでカッコ悪いですが。。)
ちなみに、scala-libraryは.ivy/cache/org.scala-lang/scala-library/jars とかにいます。