6

アプリケーションを単体テストするときに、依存性注入を学習しようとしていますが、問題が発生しました。

私はコンソールアプリケーションを作成しており、コンテナはMain()で作成および初期化され、get-propertyinとして使用できるProgram.Containerため、アプリケーションのどこからでもを呼び出すことができますProgram.Container.Resolve<..>()

私はこのようなServiceValidatorクラスを持っています:

public class ServiceValidator
{
    private readonly IConfiguration _configuration;
    private readonly IService _service;

    public ServiceValidator(IConfiguration configuration, IService service)
    {
        _configuration = configuration;
        _service = service;
    }

別のクラスで私は使用します

ServiceValidator serviceValidator = Program.Container.Resolve<ServiceValidator>();
serviceValidator.VerifyVersion();

Program.Container.Resolveセットアップされていないため、ユニットテストで問題が発生するのはこの呼び出しです。

コンテナでresolveを呼び出すのは悪い習慣ですか?ServiceValidatorインスタンスを作成しMain()てオブジェクトを渡すこともできますが、次のメソッドに渡されるオブジェクトのパラメーターが多くなるため、これはばかげているようです。

したがって、クラス内でResolveを呼び出すことは許容できると思いますが、その場合、コンテナーは単体テスト用に構成する必要があります。どうすればよいですか、コンテナをプログラムクラス以外の場所に移動する必要がありますか?あなたは何をお勧めします?

重要な場合は、UnityとC#を使用しています

ありがとう :-)

4

5 に答える 5

8

コンテナでresolveを呼び出すのは悪い習慣ですか?Main()でServiceValidatorインスタンスを作成してオブジェクトを渡すこともできますが、次のメソッドに渡されるオブジェクトのパラメーターが多くなるため、これはばかげているようです。

依存性注入をずっと使用する場合、オブジェクトに多くのパラメーターを渡す必要はありません。各オブジェクトのコンストラクターは、パラメーターとして、それ自体が直接使用する依存関係のみを持つ必要があります。直接依存関係の推移的な依存関係については認識しません。

したがって、ServiceValidatorを必要とするクラスXがある場合、クラスXにはServiceValidator型のコンストラクターパラメーターがあります。次に、あるクラスYがクラスXを使用する場合、クラスYにはタイプXのコンストラクターパラメーターがあります。YはServiceValidatorについて何も知らないため、あるクラスから別のクラスにServiceValidatorを渡す必要はありません。 Xを構築するときに使用されます。これは、多くの場合、DIフレームワークによって、または手書きのファクトリ内の1か所でのみ実行されます。

詳細については、いくつかのリンクを参照してください。

于 2009-05-04T13:55:33.433 に答える
1

私は通常、メインのような場所でコンテナーからの依存関係を解決するための呼び出しを許可しますが、それでもそれらを最小限に抑えようとします。次に、テスト クラスの初期化メソッドでコンテナーを構成します。コンテナを呼び出す必要があるテストクラスの偽の実装で初期化しました。

コンテナの初期化を必要とするものを何も呼び出さないテスト クラスは、それを無視してフェイクを使用しないようにできます。私は通常、それらのインスタンスでモックを使用します。

また、特定のコンテナーではなく、.NET Framework の何かに依存するように、 Microsoft Service Locatorも使用します。これにより、自家製の容器であっても、好きなものを何でも使用できるようになります。

于 2009-05-04T13:37:01.620 に答える
0

技術的に行っているのは、クラス内のサービスの場所です。

しばらく前にこの記事を読んだことを覚えています。

http://martinfowler.com/articles/injection.html

私のクラスでは、Resolveを使用しようとはしません。必要なときにコンテナを介してオブジェクトを作成します。ユニットテストでは、いくつかのモックライブラリとスタブクラスを使用します。

于 2009-05-04T13:55:20.843 に答える
0

コンテナの初期化子として静的クラスを使用できます。BootStrapper.cs のようなもので問題ありません。その後、コードとテストの両方でクラス メソッドを参照できます。

于 2009-05-04T13:44:33.583 に答える
0

問題は、Main メソッドをテストしようとしていることにあります。この方法では、単体テストを行うことは事実上不可能です。

次の理由により、 Main メソッドの単体テストを行わないことが最善であると私は主張します。

  • 現代の単体テストの重点は設計に関するものです
  • 単体テストでは、構成への依存を最小限に抑える必要があります。構成は、スモーク テストまたは統合テストでテストできます。
于 2009-05-04T14:24:58.883 に答える