これは少し奇妙な質問ですが、数か月間私を悩ませてきました。 Wicket + Hibernate(Mavenで構築)を使用してJPAベースのWebアプリケーションを構築し、DAOレイヤーを直接テストしたいと思います。テストに使用した特定のsrc/test/resources/META-INF/persistence.xmlファイルを作成しましたが、WTPなどとの競合が発生しています。これらの問題を回避するために、単体テストが存在する別のテストプロジェクトを作成しました。永続化ファイル間の決闘なしにJPAプロジェクトの単体テストを管理するより良い方法はありますか?
補遺:他のテストフレームワーク(TestNGなど)を使用すると、これが簡単になりますか?
mockito を試してみてください。テストは次のように機能します。
Mockitoを使用してEntityManager
を「実装」します。実際のコードの代わりに、mockitoのメソッドを使用して、「アプリケーションがgetReference()
を呼び出した場合、このオブジェクトを返す」と言います。バックグラウンドで、mockitoはJavaメソッドの呼び出しをインターセプトし、指定した値を返します。他のメソッドの呼び出しはnull
を返します。
createQuery()
のようなモックアップは同じように機能しますが、最初にQuery
のモックアップを作成してから、getReference()
と同じアプローチを使用する必要があります(クエリモックアップを返す) 。
実際のEMを使用しないため、実際のpersistence.xml
は必要ありません。
より簡単な解決策は、persistence.xml
ファイルの名前を変更するプロパティを設定できる場合ですが、これは可能ではないと思います。
役立つ他のリンク:
本番およびテストランタイムにはデュアルpersistence.xmlファイルを使用していますが、これはクラスパス関連の問題のみです(Eclipseを使用していますが、WTPプラグインに大きく依存していません) )。 2つの違いは、製品版にはエンティティ定義が含まれていないことです。
JPAのテストにモックフレームワークを使用しません。これは、テストに値を追加しないためです。テストは、PostgreSQLデータベースと通信するJPAで実際のデータアクセスを実行します。
テストへの私たちのアプローチは、永続性レイヤーのためのSpringテストフレームワーク、つまりトランザクション内テストに基づいています。私たちのアプリケーションはSpringベースですが、このアプローチは、Springテストクラスを利用したい任意のアプリケーションにも同様に使用できます。本質は、各テストはコミットされない単一のトランザクション内で実行され、最後に(tearDownで)自動的にロールバックされることです。これにより、非常に控えめで透過的な方法で、データ汚染とテスト依存の問題が解決されます。
Springテストフレームワークはマルチトランザクションテストを可能にする柔軟性がありますが、これらはテストの10%以下を構成する特別なケースです。
私たちは今でも JUnit 3.8のレガシーサポート を使用していますが、JUnit 4の新しい Spring TestContext Framework は非常に魅力的に見えます。
トランザクション内のテストデータを設定するために、ビジネスエンティティを構築する社内ユーティリティクラスを使用します。すべてのテスト間で共有されるため、維持およびサポートするオーバーヘッドは、テストデータを設定するための標準的で信頼性の高い方法を備えていることの利点よりもはるかに優れています。
Spring DIは、テストを簡潔でわかりやすいものにするのに役立ちますが、重要な機能ではありません。
SpringとSpringの単体テストを使用するのが最善の方法です。 Springでは、persistence.xmlには何も含まれていないため、2つのpersistence.xmlは必要ありません。すべてはSpringによって指定され(persistence.xmlで指定するのはすべてpersistence-unit名です)、データベースの構成を変更できます。春など。
そしてトップシェフが指摘したように、Springのトランザクションベースのユニットテストは素晴らしいです。
ここで述べたように、 http://www.devx.com/Java/Article/36785/1954 を使用すると、プロジェクトの.settings/org.Eclipse.wst.common.component
から次の行を削除して、テストリソースをウェブアプリ。
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/Java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/resources"/>