8

私は答えを見つけようとしていましたが、直接議論されていないようです。DI コンテナーを作成し、そこにすべてを登録してから、すべての依存関係を取得する必要な最上位クラスを解決する、アプリケーションのコンポジション ルートがあります。これはすべて内部で行われているため、コンポジション ルートの単体テストが難しくなります。仮想メソッド、保護されたフィールドなどを実行できますが、単体テストを実行できるようにするためだけにそのようなものを導入することはあまり好きではありません。他のクラスはすべてコンストラクター注入を使用するため、大きな問題はありません。問題は、コンポジションのルートをテストすることに意味があるのか​​ということです。いくつかの追加のロジックがありますが、多くはなく、ほとんどの場合、アプリケーションの起動中にエラーが発生します。私が持っているいくつかのコード:

public void Initialize(/*Some configuration parameters here*/)
    {
        m_Container = new UnityContainer();

        /*Regestering dependencies*/

        m_Distributor = m_Container.Resolve<ISimpleFeedMessageDistributor>();
    }

    public void Start()
    {
        if (m_Distributor == null)
        {
            throw new ApplicationException("Initialize should be called before start");
        }

        m_Distributor.Start();
    }

    public void Close()
    {
        if (m_Distributor != null)
        {
            m_Distributor.Close();
        }
    }
4

1 に答える 1

8

コンポジションルートをテストすることはまったく意味がありますか?

アプリケーションが正しく作成されているかどうかを知りたいですか? おそらくそうであり、それがテストを書く理由です。これと同じ理由で、コンポジション ルートをテストする必要があります。

ただし、これらのテストは、システムの配線の正確性を特に対象としています。単一のクラスが正しく機能するかどうかをテストする必要はありません。これは、すでに単体テストでカバーされているためです。また、クラスが他のクラスを正しい順序で呼び出すかどうかをテストする必要もありません。これは、通常の統合テストでテストする必要があるためです (MVC コントローラーを呼び出して、呼び出しがデータベースで終了するかどうかを確認することが、そのような統合テストの例です)。 )。

おそらくテストする必要があるいくつかのことを次に示します。

  • すべての最上位クラスを解決できること。これにより、すべてが正しく配線されているかどうかを確認するために、アプリケーションのすべての画面をクリックする必要がなくなります。
  • そのコンポーネントは、同等またはそれより長く存続するサービスにのみ依存します。コンポーネントが、より短い有効期間で構成された別のコンポーネントに依存している場合、そのコンポーネントはその依存関係の有効期間を「促進」し、多くの場合、再現と修正が困難なバグにつながります。この種の問題をチェックすることは重要です。このタイプのエラーは、ライフスタイルの不一致または拘束依存としても知られています。
  • アプリケーションの正確性にとって重要なデコレータやその他のインターセプト メカニズムが正しく適用されていること。デコレータは、例えば、トランザクション処理、セキュリティ、キャッシングなどの分野横断的な懸念事項を追加できます。これらの懸念事項が正しい順序で実行されることが重要です (たとえば、キャッシュをクエリする前にセキュリティ チェックを実行する必要があります)。通常の統合テストを使用してこれをテストします。

ただし、これを行うには、検証可能な DI 構成が必要です。

ただし、誰もがこの意見を共有しているわけではないことに注意してください。しかし、私の経験では、構成が正しいことを検証することは非常に価値があります。

そのため、一部の IoC コンテナーではこれらのテストが困難になる可能性がありますが、他の IoC コンテナーにはこれを支援する機能があります (残念ながら、Unity にはこれらの機能のほとんどが欠けています)。

一部のコンテナには、構成を検証するために呼び出すことができる何らかの検証メソッドがあります。「検証」の意味はライブラリごとに異なります。たとえば、Simple Injector (私は Simple Injector の主任開発者です) には、Verifyすべての登録を単純に反復しGetInstance、それぞれを呼び出して、すべてのインスタンスを確実に作成できるようにするメソッドがあります。Verify可能な限り、コンポジションルートで呼び出すことを常にユーザーにアドバイスします。たとえば、構成が大きくなると、Verify の呼び出しによってアプリケーションの起動が非常に遅くなる可能性があるため、これが常に可能であるとは限りません。それでも、それは良い出発点であり、多くの痛みを取り除くことができます. 時間がかかる場合は、いつでも呼び出しを自動テストに移すことができます。

Simple Injector の場合、これは始まりにすぎません。Simple Injector には、前述の「ライフスタイルの不一致」などの一般的な構成ミスについてコンテナーをチェックする診断サービスが含まれています。

したがって、絶対にテストする必要がありますが、これらのテストを「単体テスト」と呼ぶかどうかはわかりませんが、これらのテストを分離して (データベースや Web サービスにアクセスすることなく) 実行することはできます)。

于 2013-08-28T20:10:31.117 に答える