キャッチしたい失敗の例の1つは、テスト対象のオブジェクトがキャッシングレイヤーを使用しているが、必要に応じてデータを永続化できないことです。次に、オブジェクトにクエリを実行すると、「はい、新しい名前とアドレスがあります」と表示されますが、テストは実際に実行されていないため失敗します。
あるいは(単一責任違反を見落としている)、文字列のUTF-8エンコードバージョンをバイト指向フィールドに永続化する必要があるが、実際にはShift JISを永続化すると仮定します。他のコンポーネントがデータベースを読み取り、UTF-8が表示されることを期待しているため、要件です。次に、このオブジェクトを往復すると、正しい名前と住所が報告されます。これは、Shift JISから変換されるためです。ただし、テストではエラーは検出されません。後の統合テストで検出されることを期待していますが、単体テストのポイントは、問題を早期に発見し、責任のあるコンポーネントを正確に知ることです。
それらの1つが想定されていることを実行していない場合、独自のテストケースは失敗し、修正してテストバッテリを再度実行できます。
これを想定することはできません。注意しないと相互に依存する一連のテストを書くからです。「保存しますか?」testはテスト対象のsaveメソッドを呼び出し、次にloadメソッドを呼び出して保存されたことを確認します。「ロードしますか?」testはsaveメソッドを呼び出してテストフィクスチャをセットアップし、次にテスト中のloadメソッドを呼び出して結果を確認します。どちらのテストも、テストしていないメソッドの正確性に依存しています。つまり、どちらもテスト対象のメソッドの正確性を実際にテストしていません。
ここに問題があるという手がかりは、異なるユニットをテストしているはずの2つのテストが実際に同じことを行うということです。どちらもセッターに続いてゲッターを呼び出し、結果が元の値であることを確認します。しかし、セッター/ゲッターのペアが連携して動作するのではなく、セッターがデータを保持することをテストしたいと考えました。何かが間違っていることを知っているので、テストを修正して修正する必要があります。
コードがユニットテスト用に適切に設計されている場合は、テスト対象のメソッドによってデータが実際に正しく永続化されているかどうかをテストできる少なくとも2つの方法があります。
データベースインターフェースをモックし、適切な関数が呼び出されたことをモックに期待値とともに記録させます。これは、メソッドが想定されていることを実行することをテストするもので、従来の単体テストです。
まったく同じ意図で実際のデータベースに渡し、データが正しく永続化されているかどうかを記録します。しかし、「うん、正しいデータを取得しました」とだけ言うモック関数を使用するのではなく、テストはデータベースから直接読み取り、それが正しいことを確認します。これは可能な限り純粋なテストではない可能性があります。データベースエンジン全体は、見栄えの良いモックを作成するために使用する非常に大きなものであり、何かが間違っていてもテストに合格する微妙な部分を見落とす可能性が高いためです(たとえば、コミットされていないトランザクションが表示される可能性があるため、書き込みに使用されたのと同じデータベース接続を使用して読み取りを行うべきではありません)。しかし、それは正しいことをテストし、少なくともあなたはそれを正確に知っている モックコードを記述することなく、データベースインターフェイス全体を実装します。
したがって、JDBCを使用してテストデータベースからデータを読み取るか、データベースをモックするかは、テスト実装の単なる詳細です。いずれにせよ、同じクラスの他の間違ったメソッドと共謀して何かが間違っている場合でも正しく見えるようにする場合、分離することでユニットをテストすることができます。そのため、メソッドをテストしているコンポーネントを信頼する以外に、正しいデータが保持されていることを確認するための便利な手段を使用したいと思います。
コードが単体テスト用に適切に設計されていない場合、テストするメソッドを持つオブジェクトがデータベースを挿入された依存関係として受け入れない可能性があるため、選択の余地がない場合があります。その場合、テスト対象のユニットを分離する最良の方法に関する議論は、テスト中のユニットの分離にどれだけ近いかについての議論に変わります。ただし、結論は同じです。障害のあるユニット間の陰謀を回避できる場合は、利用可能な時間や、コード内の障害を見つけるのに効果的だと思われる他の条件に応じて行います。