2009-08-05 15 views
30

これは奇妙な質問ですが、数ヶ月間私を悩ませています。私はWicket + Hibernate(Mavenで構築)を使ってJPAベースのWebアプリケーションを構築し、DAOレイヤーを直接テストしたいと思っています。テスト用に使用した特定のsrc/test/resources/META-INF/persistence.xmlファイルを作成しましたが、WTPなどと競合しています。これらの問題を回避するために、私はユニットテストが生きる別のテストプロジェクトを作成しました。永続性ファイルの間にデュエルを持たずに、JPAプロジェクトの単体テストを管理するより良い方法はありますか?JPAベースのJUnitテストのベストプラクティス

補足:他のテストフレームワーク(TestNGなど)でこれを簡単にすることはできますか?

+0

このタイプのテストは単体テストではありません。私はタイプの統合テストだと思う。単体テストを書くときには、すべての依存関係がモックされたクラスをテストします。したがって、ユニットテストでは実際のデータベース(インメモリデータベースでさえ)を使用することは有効ではありません。 –

+0

これは完全な統合テストではありません。それは有効です!単なる単体テストではありません。 – Gilberto

答えて

16

mockitoをお試しください。テストは次のようになります。

あなたはmockitoを使用してEntityManagerを実装します。実際のコードの代わりに、 "アプリケーションがgetReference()を呼び出したら、このオブジェクトを返す"と言うのにmockitoのメソッドを使います。バックグラウンドでは、mockitoはJavaメソッド呼び出しをインターセプトし、指定した値を返すプロキシインスタンスを作成します。他のメソッドへの呼び出しはnullを返します。 createQuery()のようなものをモック

は同じように動作しますが、あなたは最初の(クエリモックアップを返す)Queryのモックアップを作成し、getReference()と同じアプローチを使用する必要があります。

実際のEMを使用していないので、実際にはpersistence.xmlは必要ありません。

もっと簡単な解決策は、persistence.xmlファイルの名前を変更するプロパティを設定できれば可能ですが、これは可能ではないと思います。

助けるかもしれないいくつかの他のリンク

+0

私はMockオブジェクトを(LDAPベースのテストのために)使ってみましたが、確かにオプションです。この具体的なケースでは、DAOが情報を返すことを保証するのではなく、実際にDBに照会してエンドツーエンドのものを検証したいと考えています。 – mlaccetti

+2

その場合、最初のリンクに解決策があります。persistence.xmlに複数の「永続性単位」を指定し、単体テストで別のものを選択できます。 –

4

我々は、生産とテストランタイムのための二重のpersistence.xmlファイルを使用しますが、それが唯一のクラスパスに関連する問題です(私たちはEclipseを使用しますが、WTPプラグインに大きく依存しません)。この2つの唯一の違いは、実動バージョンにエンティティ定義が含まれていないことです。

私たちはJPAをテストするために模擬フレームワークを使用しません。これは、テストに何の価値も追加しないためです。このテストでは、PostgreSQLデータベースと通信するJPAを使用した実際のデータアクセスが実行されます。

私たちのテスト手法は、永続化層のSpringテストフレームワーク:トランザクション内テストに基づいています。私たちのアプリケーションはSpringをベースにしていますが、Springのテストクラスを利用したい任意のアプリケーションでも同様にこの方法を使用できます。本質は、各テストがコミットしない単一のトランザクション内で実行され、最後に(tearDownで)自動的にロールバックされることです。これは、データの汚染とテストの依存関係の問題を、非常に見苦しい、邪魔にならない透明な方法で解決します。

Springテストフレームワークは、マルチトランザクションテストを可能にするために柔軟性がありますが、テストの10%を超えない特殊なケースです。

まだlegacy support for JUnit 3.8を使用していますが、新しいSpring TestContext FrameworkはJUnit 4に非常に魅力的です。

トランザクション内のテストデータを設定するために、私たちはビジネスエンティティを構築する社内ユーティリティクラスを使用します。すべてのテスト間で共有されるため、維持してサポートするオーバーヘッドは、テストデータを設定するための標準的で信頼性の高い方法のメリットがあるため、非常に軽量です。

スプリングDIはテストを簡潔かつ自己記述的にするのに役立ちますが、重要な機能ではありません。

+0

私はJUnit 4.x(4.6、最後のカウントでは、私は信じています)とSpringテスト拡張機能を使用しています。彼らは私のJPA環境を設定するのにすばらしい助けをしますが、私のproduction persistence.xmlがWEB-INF/lib/common-code.jarを参照していてテストではうまく動作しないので、まだ問題があります。 – mlaccetti

4

SpringとSpringの単体テストを使用するのが最善の方法です。 Springでは、persistence.xmlには何も格納されていないので、2つのpersistence.xmlは必要ありません。すべてがspringで指定されています(persistence.xmlで指定したものはすべて永続ユニット名です)。春など。

トップクラスの指摘したように、Springのトランザクションベースの単体テストは素晴らしいです。

+0

どのクラスをロードするのか、Springのコードを読み込むためのjarファイルを指定するのですか?私は何か重要なことを見逃したようです。 – mlaccetti

+0

私は、実行時に-javaagentを有効にし、persistence.xmlを使用するOpenJPAを使用します。 persistence.xmlではなく、Springの設定で記述されたクラスの中からOpenJPAエージェントを検索するにはどうすればよいですか? –

+0

hmmm ...私は答えが多分古いかもしれないと思います。永続クラスのリストをpersistence.xmlに指定する必要があります –

0

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"/> 
関連する問題