1

静的プロパティを必要とするメソッドがあり、単体テストを作成したいので、それをラッパー クラスでラップするとします。インターフェイスを IFoo & 具体的なクラス Foo と呼びましょう。

私のメソッドが MVC ビュー内から呼び出された場合、そのメソッドにラッパー インスタンスをどのように取得しますか?

明らかに、コントローラー コンストラクターに IFoo パラメーターを追加し、ビュー モデルに IFoo プロパティを追加し、メソッドに IFoo パラメーターを追加して、それをチェーンに渡すことができます。コントローラー、ビュー モデル、ビュー、拡張メソッド。それは私には受け入れられないようです。

これを行うためのよりクリーンな方法はありますか?

DI コンテナーが最適だと思いました。正直に言うと、これまでは必要ありませんでした。単純に、Ninject を追加し、具体的な型をインターフェイスにバインドし、メソッド内で次の呼び出しを行うだけだと思い込んでいました。

var dt = kernel.Get<IFoo>();

これは、上記のコンストラクターパラメーター/プロパティトレイル全体を回避するのに役立つと思いました。どこかからカーネル変数を取得する必要があることはわかっていましたが、スレッド/セッション/リクエストスコープで呼び出すことについて何かを見たことを覚えていると思いました。カーネルが呼び出された場所に関係なく、カーネルの同じインスタンスをインスタンス化できると思っていましたが、調べてみると、それはカーネルが呼び出しているオブジェクト インスタンスに対してのみであることがわかりました...カーネル自体ではありません。

それで、Fooのインスタンスをメソッドに渡す方法はありますか?

4

3 に答える 3

1

あなたの正確なユースケースがわからないので、私が提案するものは適切かもしれませんし、そうでないかもしれません。私がこれを処理した方法はいくつかありますが、それはテストしている場所によって異なります。拡張メソッドの観点からは、拡張のDateTime単体テストに適切な値を手動で挿入するだけでよいと思います。に対して 値をテストする必要がある場合DateTime.UtcNow、それは少し異なりますが、2 番目のパラメーターで on を指定しない場合はDateTime、デフォルトで nullable を使用して処理できます。DateTime.UtcNow

   public static IHtmlString RegularExtension(this HtmlHelper helper, DateTime when)
   {
      ...
   }

   public static IHtmlString ComparisonExtension(this HtmlHelper helper, DateTime when, DateTime? now = null)
   {
       var nowDate = now ?? DateTime.UtcNow; // verified by inspection, tests use specified values
       ...
   }

または、後者の場合、null 合体演算子に慣れていない場合は、2 つの方法を使用してください。単一のパラメーターを取るパブリック パラメーターと、両方を使用するプライベート パラメーター。リフレクションを使用してプライベート メソッドをテストし、パブリック メソッドをプライベート メソッドに委譲するだけです。また、両方のパラメーターが必要な単一の方法を使用し、常に両方の値をモデルに組み込むことを検討することもできます。

コントローラーの観点から、現在の時間に一貫した値を使用する必要がある場合は、ラッパーをコントローラーに挿入し、モデルにラッパーからの「ラップされていない」値を設定することができます。そうすれば、下流のすべてをラッパーに結び付けることなく、コントローラーがモデルの値を適切に設定することをテストできます。重要なのは、すべてのコードが、DateTime.UtcNow直接呼び出すのではなく、注入された (およびアンラップされた) 値を使用することです。これらのクラスのテストの観点からは、値がどこから来るのかはわかりません。値が上流から供給されているだけです。

   public FooController(IDateTimeWrapper timeWrapper)
   {
       var model = new FooModel { Now = timeWrapper.Unwrap(), ...  };

       ...

       return View(model);
   }
于 2013-04-20T21:38:02.037 に答える
1

ViewModel または View が Ninject によっても作成されている場合は、IFoo をコンストラクターの依存関係として追加し、それを挿入できるはずです。に直接アクセスしKernelてインスタンスを解決したい場合 (通常はこれは最善の方法ではありません)、 を挿入してIResolutionRootGet を呼び出すことができます。

于 2013-04-21T12:00:11.353 に答える