Hibernate / Spring / JUnitを使用した複雑なデータベース状態のセットアップと破棄

StackOverflow https://stackoverflow.com/questions/822846

  •  03-07-2019
  •  | 
  •  

質問

私は、個々のテストメソッドを実行する前にかなり広範なデータベースのセットアップを必要とするユニットテストのクラスを持っています。このセットアップには長い時間がかかります:できれば手近な質問とは関係のない理由で、SQLダンプではなくプログラムでDBにデータを入力する必要があります。

私が抱えている問題は分解です。 dbセットアップフェーズで行われたすべての変更を簡単にロールバックするにはどうすればよいですか?

現在、Hibernate + Spring Transactional Testingサポートを使用しています。これにより、個々のテストメソッドがトランザクションにラップされます。

1つの解決策は、各テストメソッド内でdbセットアップを実行し、dbセットアップが自動的にロールバックされるようにすることです。ただし、各メソッドはデータベースを再準備する必要があるため、テストメソッドの実行には永遠に時間がかかります。

他のアイデアはありますか?基本的には、dbセットアップを実行し、個々のテスト(それぞれが実行後にロールバックされるトランザクションにラップされている)を実行してから、初期dbセットアップをロールバックする方法を探しています。これをHibernate / Spring / Junitの方法で機能させるためのアイデアはありますか? Hibernate「すべてのテーブルをドロップ」がありますか?同等のコマンド?

役に立ちましたか?

解決

特定のデータベースベンダーにこだわっていますか?そうでない場合は、 HSQLDB などのメモリ内データベースを使用できます。テストが完了したら、状態を破棄するだけです。これは、テストスイートの開始時に(つまり、プログラムによるセットアップの前に)テーブルを空にできる場合にのみ適切です。

まだテーブルを作成する必要がありますが、Hibernateを使用してすべてがきちんとマッピングされている場合は、hbm2ddlを使用してテーブルを生成できます。必要なのは、セッションファクトリの定義に test を追加するだけです:

<session-factory>
    ...
    <property name="hibernate.hbm2ddl.auto">create</property>
    ...
</session-factory>

このソリューションが適用可能と思われる場合は、詳しく説明します。

他のヒント

Junit 4の@AfterClassアノテーションをご覧ください。このアノテーションは、テストが完了すると実行されます。

http://cwiki.apache.org/DIRxDEV/junit4-primer.html

DNUnitはこの点で役立ちます。 必要に応じて、テストケースごとに個別のデータセットを作成できます。

DBUnitはこれに大いに役立ちます。理論的にはJDBCで自動コミットをオフにすることもできますが、毛むくじゃらになるでしょう。最も明らかな解決策は、テストを実行する前に、DBUnitを使用してデータを既知の状態に設定することです。何らかの理由でテストの実行後にデータを戻す必要がある場合は、すべてのテストを実行するスイートで@AfterClassを見ることができますが、一般的にはテストを設定して実行する方が良いと考えられています。テストが失敗した場合、それは別のテストのクリーンアップに失敗したためにその環境が整っていなかったからではありません。各テストがその環境を直接設定することを確認します。

検討したい解決策の1つは、「手動」を使用することです。 dbのトランザクションのロールバックまたは補正。 (そうでない場合は、Hibernateエンティティへの簡単なアドオンにする必要があります)すべてのエンティティには、テーブルにINSERTされた日時を示すdatetime create属性があります。 dbセットアップメソッドは、他のすべての前に時間を記録する必要があります。次に、dbのセットアップで時間を記録した後に作成されたすべてのエンティティを削除するdbの簡単な手順があります。

もちろん、これはdbセットアップの更新では機能しません...しかし、更新の数が限られている場合は、このタイプのデータの元のイメージを保存し、dbの分解中に復元することを検討してください。

比較的小さなデータベースを使用していて、そのバックアップ/エクスポートを比較的高速に実行できるDBMS(MS SQL Serverなど)を使用している場合は、テストの前にデータベースのバックアップを作成して、すべてのテストが完了しました。これにより、開発/テストデータベースをセットアップし、すべてのテストの開始状態として使用できます。

ネイティブJDBCを使用して、「バックアップデータベース」と「データベースの復元」T-SQLの中間テストを実行しましたが、かなりうまくいきました。

ただし、このアプローチは、ローカルマシンにDBMSサーバーを配置し(妥当な速度のため)、十分な特権(これは問題ではないはずです)を持ち、データベースの合計サイズが数十MB-少なくとも私の経験では。

単体テストを実行するためにデータベースへの接続が必要な理由はありますか?データベースとのやり取りを模倣できるように、クラスをリファクタリングする方が簡単かもしれません。 EasyMock(www.easymock.org)とのインターフェースだけでなく、クラス(いくつかの例外を除く)をモックできます。

クラスが接続されたデータベース内の複雑な既存の状態に依存している場合、モックを使用してより高速に実行されるテストを記述する方が簡単でしょう。プロジェクトのサイズやテストの実行頻度はわかりませんが、特に大規模なプロジェクトでは、実行時間を考慮する必要があります。

Hibernateにはきちんと文書化されていない未知の機能があります。データベーススキーマ生成直後のSessionFactory作成中にSQLスクリプトを実行して、新しいデータベースにデータをインポートできます。クラスパスルートにimport.sqlという名前のファイルを追加し、createまたはcreate-dropをhibernate.hbm2ddl.autoプロパティとして設定するだけです。

http://in.relation.to/Bloggers/RotterdamJBugAndHibernatesImportsql

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top