it-swarm-ja.com

モック依存関係を設定するときのユニットテストのジレンマに対する答えは何ですか?

SwiftのiOSにVIPERアーキテクチャを実装しようとしています。

私が抱えている問題は、オブジェクトグラフの設定方法です。私の問題とは関係がないので、ルーターとエンティティは無視してください。それは私たちにインタラクター、プレゼンター、そしてビューを残します。

インタラクター-ビジネスロジック、状態があり、機能し、コマンドを受け入れます。プレゼンター-抽象データをプレゼンテーション形式に変換するか、インタラクターに作業を依頼します。表示-提示可能な情報を提示し、アクションをPresenterに送信して、ビジネスロジック要求に変換します。

これら3つのコンポーネント間の通信は双方向であり、InteractorとViewは相互に認識しません。
インタラクター<->プレゼンター<->ビュー。

すべてプロトコルとして定義されています。 (他の言語のインターフェース...)各具象コンポーネントは対応するプロトコルに準拠します(つまり、インターフェースを実装します)...そしてそれらのコンポーネントのみインターフェースとしてお互いを参照してください。

ここに問題があります:

プレゼンターが正しく機能するには、ビジネスロジックと状態が存在するInteractorインスタンスへの参照が必要です。ビューについても同じことが言えます。適切に初期化されたPresenterインスタンスへの参照がないと正しく機能しません。

私には2つの選択肢があります:

オプションA:1)プレゼンターには、インタラクターインスタンスを取り込む必要な初期化子があります。 2)ビューには、プレゼンターインスタンスを取り込む必要なイニシャライザーがあります。 3)これをプロトコルで実施します。

オプションB:1)プレゼンターにはpublic .interactor変数があり、これはプレゼンターインスタンスで設定可能です。 2)ビューにはpublic .presenter変数があり、これはビューインスタンスで設定可能です。

初期化子を使用したオプションAは、物事が正しい順序でセットアップされ、有効な状態に初期化されることを保証するメカニズムを提供します。ただし、これにより、ユニットテストで同じメカニズムを複製する必要があります。モック、これらのプロトコルのスタブ実装では、実際にこれらのイニシャライザーが必要であり、相互に初期化する必要があります。つまり、匂いがする相互に依存するモックのチェーンがあります。 。

オプションBは、モックチェーンの問題を防ぎますが、オブジェクトが無効な状態になる可能性があるか、依存関係チェーンを設定するルーターメソッドを実際に単体テストする必要があります。ただし、ユニットテストケースごとに1層のモックしか処理できなくなります。少なくとも理論的には、私はまだそれを試していないと思います。

どちらのアプローチが正しいですか?それとも他のアプローチはありますか?アドバイスしてもらえますか?

1
Earl Grey

Interactorインスタンスでの具体的なPresenterの依存関係、およびPresenterインスタンスでの具体的なViewの依存関係は、本質的にそれぞれのインターフェイスの一部である依存関係ではありません。
むしろ、それらは具体的な実装クラスからの要件です。
たとえば、モックプレゼンターは、インタラクションインスタンスがなくても完全にうまく機能します。

これは、正しい実装がオプションAに近いことを意味しますが、この要件をプロトコルに配置することはありません。
そうすれば、ルーター(プレゼンターとビューがインスタンス化される場所である場合はとにかく具象クラスを知る必要があります)が必要なリンクなしでビューまたはプレゼンターを作成することはできませんが、チェーンは避けますテストの依存関係の。