たとえば、Interactor から Presenter へのコールバックを使用すると、Presenter のテストが難しくなる可能性があります。
プレゼンターが (Interactor から送信された) 入力を処理する方法のテストを作成する場合、テストでは、Presenter で Interactor を呼び出す何らかのメソッドを呼び出す必要があります。これにより、Interactor はデータを Presenter に送信します。 .
Presenter に Interactor によって定義されたプロトコルを実装させることで、テストは Presenter で適切な入力メソッドを直接呼び出すことができます。
プロトコルを宣言する限り、オブジェクトではなくロールのモックのスタイルで TDD を実践しています ( http://www.jmock.org/oopsla2004.pdf )。プロトコルは、オブジェクトがどのようにそれを行うかではなく、何をするか (その役割) に焦点を当てることで、より良い抽象化を提供するのに役立ちます。
プロトコル自体は、単体テストにはほとんど価値がありません。単体テストは、テスト中のシステムの依存関係のテスト ダブル ( http://martinfowler.com/bliki/TestDouble.html ) を提供します。依存関係を具象クラスとして公開したとしても、テスト用のテスト ダブルを作成できます。
Objective-C では、OCMock ( http://ocmock.org ) や OCMockito ( https://github.com/jonreid/OCMockito )などのモッキング ライブラリを使用して、オブジェクトのスタブ、スパイ、またはモックを作成できます。具体的なクラス。
Swift では、依存関係として使用される各具体的なクラスをサブクラス化することで、テスト ダブルを作成できます。
つまり、プロトコルは単体テストを容易にするために使用されるのではなく、より高いレベルの抽象化で、アプリケーションが何をするかを記述するために使用されます。
以下は、抽象プロトコルを持つことが実際にどのように有益であったかを示す例です。
ProfileUserActions
ユーザーが画面上で実行できるアクションchangeName
を表すプロトコルを作成しましたchangeAddress
。プレゼンターは を実装し、ビューはを依存関係としてProfileUserActions
受け入れました。ProfileUserActions
ユーザーが画面上のボタンをタップすると、ビューは適切なメッセージをそのuserActions
オブジェクトに送信します。
分析を追加したいと思ったとき、新しい独立したProfileAnalytics
クラスを作成することができましたProfileUserActions
。ビューとプレゼンターの間に分析オブジェクトを挿入しました。これにより、ビューまたはプレゼンターを変更することなく、アプリが分析をキャプチャできるようになりました。