私は現在、SpringベースのWebアプリケーションを開発しています。このアプリケーションでは、ほとんどすべての操作でデータベース内の何かが作成、更新、削除されます。データベースでレコードを作成/更新する必要があるかどうかを確認するためのロジックの大部分は、条件をチェックすることです。
ユニットテストを試してみたいのは、リクエストの変更やリファクタリングの際にしばしば回帰エラーに出会うためです。ほとんどのバグはデータベースの変更によるものですが、コードにそれらの変更を完全に反映していません。私は今、ウェブ開発の経験がありますが、それを止めるだけでは十分ではないようです。
私のコントローラー/サービスは実際にはそれほど複雑ではありません。私はHttpRequestから送信されたバインディングオブジェクトを取得します条件を確認&DBのレコード。場合によっては、システムがデータベースを読み取り、いくつかのレコードを取り出して操作し、他のレコードを更新する必要があります。コーディング作業の多くは、インターフェイス(HTML/CSS/Javascript)にも依存しています。
ユニットテストを調査しています。データベースの操作に関しては、テストが遅くなるため、ユニットテストではなくなったと聞きました。本当?それで、私のプロジェクトが非常にデータベース操作である場合、単体テストを使用すべきではありませんか?
また、テストを迅速化できるDBUnitといくつかのインメモリデータベースについても聞きました。それらを使用する必要がありますか?そして、どうすればデータベース操作のための優れたユニットテストを書くことができますか?
おそらくユニットテストとintegrationテストが必要です。単体テストでは、たとえばコントローラー/サービスを個別にテストします。これを実現するために、たとえばEasymockやMockitoなどのモックフレームワークを使用して、データベースへの依存関係を削除できます。
統合テストは、コントローラー/サービスからデータベースに至るまでのすべての段階で行う必要があります。統合テストと同じ基本フレームワークを使用して、統合テストを作成できます(最も人気のあるものとしては、JUnitまたはTestNG)。私は個人的には、DBUnitを使用してデータベースにデータを事前入力し、テスト後にデータベースの状態を確認しています。インメモリデータベースIMOを使用するかどうかは、永続化レイヤーに大きく依存します。たとえば、独自のクエリを生成するJPAフレームワークを使用する場合は、メモリ内データベースを用意するのが好きです。独自のSQLクエリを作成する場合、構文が同等であるかどうかを確認できないため、本番環境のターゲット以外のDBを使用することは困難な場合があります。インメモリH2データベースは、構文がDB2で機能することを必ずしも意味しません。ストアドプロシージャを使用する場合、これはさらに問題になります。
優れた統合テスト自体は単独で実行されます。つまり、テスト間の依存関係を回避するために、各テストの前にデータベースをセットアップする必要があります。テストの成功は、テストが実行される順序に依存する必要はありません。操作を実行した後、何らかのアサーションを使用して、データベースの状態が期待どおりかどうかをテストする必要があります。たとえば、DBUnitには、データセットまたはテーブルを比較するための独自のアサートがあります。
また、テストを迅速化できるDBUnitといくつかのインメモリデータベースについても聞きました。それらを使用する必要がありますか?
はい。
そして、どうすればデータベース操作のための優れたユニットテストを書くことができますか?
他の単体テストを書くのと同じ方法です。
クラス(またはメソッド)の定義されたインターフェイスを見て、機能するはずのときに機能し、機能しないときに機能することを示すテストを記述します。
単体テストの要件に一致する行をデータベースに配置する必要があるため、セットアップは多少複雑になる場合があります。