1つのメインクラスと2つの小さなクラスにリファクタリングされたクラスがあります。メインクラスはデータベースを使用し(多くのクラスと同様)、メールを送信します。メインクラスが持つようにIPersonRepository
し、IEmailRepository
彼の順番に2つのより小さいクラスに送信する注入しました。
ここで、メインクラスの単体テストを行い、クラスの内部動作を単体テストしないことを学びました。ユニットテストを壊すことなく内部動作を変更できるはずだからです。
クラスが使用するようしかし、IPersonRepository
とIEmailRepository
、私はHAVEのためのいくつかの方法について(モック/ダミー)の結果を指定しますIPersonRepository
。メインクラスは、既存のデータに基づいていくつかのデータを計算し、それを返します。それをテストしたい場合、IPersonRepository.GetSavingsByCustomerId
戻り値x を指定せずにテストを作成する方法がわかりません。しかし、それから私のユニットテストは、どのメソッドをモックするか、そしてどのメソッドをモックしないかを「知っている」ので、内部動作を「知っている」。
テストは内部を知らずに、依存関係を注入したクラスをどのようにテストできますか?
バックグラウンド:
私の経験では、このような多くのテストはリポジトリのモックを作成し、モックに適切なデータを提供するか、実行中に特定のメソッドが呼び出されたかどうかをテストします。いずれにせよ、テストは内部について知っています。
今、私はテストが実装について知るべきではないという理論についてのプレゼンテーションを見ました(以前聞いたことがあります)。第一に、それがどのように機能するかをテストしていないためです。また、実装を変更すると、実装を「知っている」ためすべての単体テストが失敗します。私はテストが実装に気付かないという概念が好きですが、それを達成する方法がわかりません。
IPersonRepository
オブジェクトを予期するとすぐに、そのインターフェイスとそれが記述するすべてのメソッドは「内部」ではなくなるため、実際にはテストの問題ではありません。本当の質問は、「クラスを公開することなくクラスを小さな単位にリファクタリングする方法」です。答えは「これらのインターフェースを無駄にしない」です(例えば、インターフェースの分離の原則に従うことによって)。@DavidArnoの答えの私見ポイント2です(別の答えでそれを繰り返す必要はないと思います)。