2009-05-05 9 views
8

私は、個々のテストメソッドを実行するにはかなりのデータベース設定が必要なユニットテストをしています。このセットアップには長い時間がかかります。その時点で問題になっていないと思われる理由から、SQLダンプではなくDBをプログラム的に実装する必要があります。Hibernate/Spring/JUnitを使用した複雑なデータベース状態の設定と解除

私が持っている問題は解体です。 dbセットアップ段階で行われたすべての変更を簡単にロールバックするにはどうすればよいですか?

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

解決策の1つは、各テスト方法内でdb設定を行うことです。これにより、db設定が自動的にロールバックされるようになります。しかし、各メソッドはデータベースを再作成する必要があるため、テストメソッドは永遠に実行されます。

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

答えて

7

特定のデータベースベンダーに悩まされていませんか?そうでない場合は、メモリ内のデータベース(HSQLDBなど)を使用できます。テストが終わったら、あなたはただの状態を捨てるだけです。これは、テストスイートの開始時(プログラムの設定前)にテーブルを空にすることができる場合にのみ適切です。

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

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

このソリューションが適用思われる場合、私はそれについて詳しく説明することができます。

+0

時々私は最も簡単なオプションを忘れています。ボーナスはあなたを指します。 –

+0

解決策としてこれを受け入れることは、個々のテストごとにdb setup/tear downを選択したことを意味しますか? –

+0

私は静的な@BeforeClass Junitメソッドを使って同じクラスで定義された一連のテストのためにdbを一度セットアップしました。しかし、JUnitの@Beforeメソッドでテストごとに行うのは簡単です。 –

0

DNUnitは、この点であなたを助ける必要があります。 必要に応じて、個別のテストケースごとに個別のデータセットを作成できます。

0

これでDBUnitは多くの役に立ちます。あなたは理論的にはJDBC上で自動コミットをオフにすることはできますが、それは髪の毛が出るでしょう。最も明白な解決策は、テストを実行する前にDBUnitを使用してデータを既知の状態に設定することです。何らかの理由でテストを実行した後にデータが必要な場合は、すべてのテストを実行するスイートで@AfterClassを見ることができますが、テストを設定して実行する方が一般的には良い方法ですテストが失敗した場合は、別のテストをクリーンアップできないために事前環境がなかっただけではないことに注意してください。各テストが環境を直接設定するようにします。

+0

はDBUnitのが問題で除外されたSQLスクリプトと概念的に等価で使用していないでしょうか? – topchef

+0

DBUnitについて詳しくは触れていませんでしたが、私はDBUnitに精通しており、DBをプログラム的に生成する方が簡単な場合には、大量のDBUnitテストフィクスチャを維持する必要がないため、避けています。しかし、私は、よりよい解決法がない弾丸に噛み付くかもしれません。 –

0

「手動」のロールバックを使用するか、DBの解凍でトランザクションを補償することを検討してください。私は仮定しています(そうでなければ、Hibernateエンティティへの簡単なアドオンでなければなりません)。すべてのエンティティは、テーブルにINSERTされた日時を示すdatetime create属性を持っています。 db setupメソッドは、他のすべてのものよりも前に時間を記録する必要があります。次に、db setupで記録された時間の後に作成されたすべてのエンティティを削除するdb tear downの簡単な手順があります。

もちろん、これはdb setupのアップデートではうまくいかないでしょう。しかし、更新回数が限られている場合は、このタイプのデータのための元のイメージを保存し、db tear down中に復元することを検討してください。

0

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

「バックアップデータベース」と「データベースの復元」T-SQLテストを実行しているネイティブJDBCで行いましたが、正常に動作しました。

しかし、この方法は、(妥当な速度のために)ローカルマシン上にDBMSサーバーを置くこと、十分な特権(問題ではない)、およびデータベースの合計サイズが数十を超えないことMBで - 少なくとも私の経験では。

0

ユニットテストを実行するためにデータベースに接続する必要があるのはなぜですか?クラスをリファクタリングする方が簡単なので、データベースとのやりとりを模擬できるように思えます。 EasyMock(www.easymock.org)とのインターフェースだけでなく、クラスを(いくつかの例外を除いて)モックすることができます。

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

0

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

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

関連する問題