これは単純な質問かもしれませんが、私はjunitフレームワークとhibernateフレームワークの両方に不慣れであり、主にhibernateを呼び出すアプリケーションの単体テストを行うための最良の方法は何か、またはそうする必要があるかどうか疑問に思っていました。
ここでのベストプラクティスは何ですか?
編集:
ここでは春が大きな提案のようです。残念ながら、これは1つのプロジェクトに食い込むには少し多すぎるかもしれません。 Junit、Hibernate、Springはすべて私にとって新しいものであり、これらはすべて私が身に付けたいテクノロジーですが、それらすべてを1つのプロジェクトに組み込むことは私には圧倒されるかもしれません。
チュートリアルや本の提案へのリンクは大歓迎です。
単体テストと統合テストの違いに注意してください。
単体テストは、外部の依存関係のないコードをテストする必要があります。これらの依存関係は、JMockなどのフレームワークを使用してモックされます。
統合テストも重要ですが、それらの主な欠点は、実行に時間がかかることです。数千の真の単体テストを数秒で実行できますが、統合テストと同じではありません。
プロジェクト/開発チームの規模によっては、統合テストよりも真の単体テストを優先したい場合があります。どちらのスタイルのテストも重要ですが、リソースが必要な場合は、単体テストを使用する方がよい場合があります。
私は、Web(Spring MVCを使用するとこれは簡単です)とサービスレイヤー、およびドメインオブジェクトを単体テストするアプリケーションを自分で作成しました。しかし、遅い統合テストをたくさん書きたくなかったので、DAOをそのままにしました。スタッフの人数が多ければ、統合テストも行っていただろうが、この場合、費やした時間に見合うだけの価値はないと感じた。
ベストプラクティスについて:
可能であれば、テストの実行に組み込みデータベースを使用します。これにより、テストを実行するためだけに完全にデプロイされたリレーショナルデータベースが不要になります(ローカル、または継続的ビルドサーバーがある場合)。そうすれば、ロールバックなどについて(必然的に)心配する必要もありません。必要なときにデータベースを再作成するだけです。組み込みデータベースを使用したテストでは、特定の本番データベースを使用するときに発生する可能性のある特性はテストされませんが、コードはテストされます。これで十分です。
また、JUnitの拡張機能である DbUnit を使用して、Hibernateテストを実行する前に、データベースを予想される行で簡単に埋めて、既知の状態にすることもできます。
ベストプラクティス? Springを使用して、すべてのテストをトランザクションにします。テストを実行し、すべての変更をロールバックして、データベースの状態を変更しないようにします。
テストにはメモリ内のhsqldbを使用するのが好きです。各休止状態のPOJOのプロセスは次のとおりです。
DAOの場合、メソッドを正確にテストするのに十分なオブジェクトを作成して永続化し、テストを実行して、他のテストと干渉しないように必要に応じてオブジェクトを削除します。
Hibernateソースには多くの単体テストが含まれているので、それらを調べて同様のアプローチを採用することをお勧めします。
また、サンプルアプリケーションが本「JavaPersistencewithHibernate」用に開発した CaveatEmptor も見ることができます。
ドメインリッチモデルにHibernateを使用している場合、ドメインロジックの単体テストはPOJOのテストと同じくらい簡単で、Hibernateが邪魔になりません。ここでの唯一の注意点は、双方向マッピングの場合、単体テストのためにオブジェクトを両側に設定する必要がある場合があります。
データベースとの統合テストは、通常、単純なマッピングでは行われません。ただし、単一テーブル継承などの絶妙なマッピングの場合に推奨されます。ここで覚えておくべき唯一のことは、データベースに明示的にフラッシュする必要がある場合があるということです。
リクエストをHibernateに渡す単純なレイヤーを記述します。次に、 EasyMock または JMock のようなモックライブラリを使用して、Hibernate-veneerレイヤーがアプリケーションクラスによって正しく呼び出されていることを表明します。これは、部分的に完全な JMock book (「すべてがモックされている」というテスト臭までスクロールダウン)でうまく説明されています。
2つのケースをテストするのは簡単です:
実用的な場合は、エンティティの保存または読み込みについて知らない関数でさまざまな計算と変換を実行します。これらの純粋関数を作成できれば、はるかに優れています。
データベースから読み取らずにデータベースに保存するだけの関数の場合、テスト時に保存しないことを選択できます。
#2を実行する最も簡単な(最も粗雑な)方法は、関数にreallyUpdate
パラメーターを追加し、各「保存」呼び出しを次のように囲むことです。
if (reallyUpdate) {
HibernateUtil.saveOrUpdate(theThing);
}
私にとって、これらは最も低いぶら下がっている果物でした。
確かに、Hibernateで記述されていない場合は、永続性層を単体テストしますね。
Hibernateを使用して実装される特定の永続化インターフェースを作成し、いくつかのサンプルオブジェクトをインスタンス化し、CRUD操作を実行し、操作が成功したことをアサートするようにJUnitに要求します。他のクラスと同じです。
あなたはここで助けるために春を使うことができます。
優れた単体テストフレームワークがあり、CRUD opsをテストしてから変更をロールバックするために使用できます。データベースを毎回リロードする機能がない場合は、優れています。