次の課題がありますが、良い答えが見つかりません。モッキング フレームワーク (この場合は JMock) を使用して、単体テストをデータベース コードから分離できるようにしています。データベース ロジックを含むクラスへのアクセスをモックし、DBUnit を使用してデータベース クラスを個別にテストしています。
私が抱えている問題は、ロジックが概念的に複数の場所で複製されているパターンに気付いていることです。たとえば、データベースに値が存在しないことを検出する必要があるため、その場合、メソッドから null を返すことがあります。したがって、データベースとの対話を行い、null を適切に返すデータベース アクセス クラスがあります。次に、モックからnullを受け取り、値がnullの場合に適切に動作するようにテストされるビジネスロジッククラスがあります。
将来、動作を変更する必要があり、状態がより複雑になったために null を返すことが適切でなくなったとしたら、値が存在しないことを報告するオブジェクトと、からの追加の事実を返す必要があります。データベース。
ここで、データベース クラスの動作を変更してその場合に null を返さないようにすると、ビジネス ロジック クラスは引き続き機能しているように見え、バグは QA でのみ検出されます。メソッドの使用法。
私は何かが欠けているように感じました。この概念の重複を回避するためのより良い方法が必要です。または、変更された場合に変更が反映されないという事実が単体テストに失敗するように、少なくともテストを実施する必要があります。
助言がありますか?
アップデート:
私の質問を明確にしてみましょう。コードが時間の経過とともに進化するとき、モックを介してテストされたクラスとモックが表すクラスの実際の実装との間で統合が壊れないようにする方法を考えています。
たとえば、最初に作成されたメソッドがあり、null 値を想定していない場合があったため、これは実際のオブジェクトのテストではありませんでした。その後、(モックを介してテストされた) クラスのユーザーは、特定の状況下でパラメーターとして null を渡すように拡張されました。実際のクラスがnullについてテストされていなかったため、統合が壊れました。最初にこれらのクラスを構築するとき、構築しながら両端をテストするので、これは大したことではありませんが、詳細を忘れがちな 2 か月後に設計を進化させる必要がある場合、間の相互作用をどのようにテストしますか?これらの 2 つのオブジェクトのセット (モックと実際の実装を介してテストされたもの)?
根底にある問題は重複 (DRY 原則に違反している) の 1 つであると思われます。関係は概念的なものですが、実際の重複コードはありません。
[Aaron Digulla の回答に対する 2 回目の編集後に編集]:
そうです、それはまさに私がやっていることです(DBUnitを介してテストされ、テスト中にデータベースと対話するクラスでDBとのさらなる対話があることを除いて、それは同じ考えです)。ここで、結果が異なるようにデータベースの動作を変更する必要があるとします。モックを使用したテストは、1) 誰かが覚えているか、2) 統合で壊れない限り合格し続けます。したがって、データベースのストアド プロシージャの戻り値 (たとえば) は、モックのテスト データで本質的に複製されます。重複について気になるのは、ロジックが重複していることです。これは、DRY の微妙な違反です。その通りなのかもしれませんが (結局のところ、統合テストには理由があります)、代わりに何かが足りないと感じていました。
[バウンティ開始時の編集]
アーロンとのやり取りを読むと、問題の要点に到達しますが、私が本当に探しているのは、明らかな重複を回避または管理する方法についての洞察であり、実際のクラスの動作の変化が壊れたものとしてモックと相互作用する単体テスト。明らかにそれは自動的には起こりませんが、シナリオを正しく設計する方法があるかもしれません。
[バウンティの授与に関する編集]
時間を割いて質問に答えてくれたすべての人に感謝します。勝者は、2 つのレイヤー間でデータを渡す方法について新しいことを教えてくれ、最初に答えにたどり着きました。