web-dev-qa-db-ja.com

DAOユニットテスト

EasyMockと、それをDAOクラスのユニットテストや「外部コンテナー」テストに使用するためのチュートリアル/例を見てきました。ただし、それらのほとんどは、代わりにサービスレイヤーのテストについて話し、DAOクラスをモックしていると思います。私は少し混乱していますが、それは本当にDAOレイヤーをユニットテストする方法ですか?

DBおよびEJBと対話するテストは、実際には統合テストであり、単体テストではないと言う人もいますが、SQLが正しいかどうか(ORMがないと仮定)、DAOが実際のデータから正しいデータを挿入/照会するかどうかをどのように知ることができますか(読み取り、本番データベースと同様のローカルデータベース)データベース?

DBUnitはそのような状況の解決策であると読みました。しかし、私の質問は、DBUnitの「外部コンテナ」のようなフレームワークの使用についてです。 DAOが一部のEJBに依存している場合、トランザクションをどのように処理するか、挿入物の他のテーブルを更新するトリガーがある場合はどうなりますか?

そのような依存関係を持つDAOのみを単体テストするための最良の方法は何ですか?

23
Dchucks

個人的には、ある種のテストデータベース、できればアプリが本番環境で使用するのと同じタイプのデータベース(明らかに同じデータベースではない)をヒットすることでDAOを単体テストします。

そうすれば、実行中のデータベースに依存しているため、テストは統合テストに近いと思います。このアプローチには、実行中の実稼働環境に可能な限り近いという利点があります。テスト構成が必要であり、実行中のテストデータベース(マシンのローカルまたは環境内のどこか)が必要であり、テストの実行に時間がかかる可能性があるという欠点があります。また、テストの実行後に必ずテストデータをロールバックする必要があります。

DAOがテストされたら、必ずそれらをモックしてサービスの単体テストを行います。

31
hvgotcodes

通常、DAOのアイデアは、データアクセスコードのラッパーを最小限にすることです。そのため、データベースへのマッピング以外にテストするものはなく、モックを使用した単体テストは役に立ちません。モックでテストする価値のあるロジックがDAOに実際にある場合は、DAOパターンを誤用しており、ロジックはサービス内にある必要があるという議論がなされる可能性があります。

データベースへのマッピングをテストする場合 DBUnit は、テストの前に開始データセットを指定して、テストが既知の状態から開始できるようにし、テストの終了状態を指定できるため便利です。データはあるべきなので、何が期待されているかを主張するユニットテストコードをたくさん書く必要はありません。

理想的には、データベースを抽象化するHibernateのようなツールがある場合は、H2やHSQLDBなどのインメモリデータベースを使用して取得できるため、テストの実行が速くなり、作成するデータベースがありません。実際のデータベースを使用する必要がある場合は、他のプロセスに影響を与えたり影響を受けたりすることなくデータを作成および削除できるように、テストにデータベースが含まれていることを確認してください。実際には、ローカル環境とCI環境の両方でデータベースを自分で使用することはほとんどなく、インメモリデータベースを使用する方がはるかに実用的です。

16
Nathan Hughes

Koyaの回答を補完するものとして、DAOテストにHSQLDBを使用できます。プロジェクトでSpringとHibernateを使用していると思います。 HSQLDBを指すために個別の構成ファイルが必要になり、テストを実行する前にデータを挿入する必要があります。 HSQLDBで実行できることにはいくつかの制限がありますが、クエリや結合として一般的に使用することは問題ありません。このソリューションを使用すると、ジェンキンスなどの継続的な環境で使用できます。統合テストではHSQLDBを使用できるため、この部分はモックされていません。

3
Tiago Ferraz

DaoとServiceAPIのテストにHSQLDBを使用しています。パフォーマンスは良好で、トランザクションもサポートします。私はEJBを使用していません。私はHibernateを使用しています。

別のデータベースでテストを実行すると、サポートされているデータベースの問題の一部がマスクされる可能性があることを認識している問題がいくつかあります。しかし、そのような問題は、スモーク&受け入れテストで捉えるべきだと思います。

よろしく、コヤ

最終的には、コンテナーの外部で実行できる単体テストを作成し、データベースを稼働させ、トランザクションサポートでスタンドアロンのトランザクションマネージャー(Bitronix)を使用することにしました。また、ロールバックすることもできます。私はこれがまだテストを純粋なユニットテストにしないと思います...このアプローチについてのあなたの意見を聞いてみたいです。

1
Dchucks