2016-12-12 12 views
0

私はViewModelを持っています。これは、初期化されるとオブジェクトのリストを作成します。これらのオブジェクトは、IoCからのインターフェイス実装を解決することによって作成されます。これはどのようにテストする必要がありますか?

ビューモデル

public class ApplianceViewModel : IAppliance 
    { 
     private List<IHardware> HardwareItems {get; set;} 

     public ApplianceViewModel() 
     { 
      HardwareItems = new List<IHardware>(); 
      var hardware1 = Constants.Kernel.Get<IHardware>(); 
      var hardware2 = Constants.Kernel.Get<IHardware>(); 

      HardwareItems.Add(hardware1); 
      HardwareItems.Add(hardware2);   
     } 
    } 

kernelがヌルであるように上記初期化が失敗するユニットテスト

[TestClass] 
public class ApplicanceViewModelTest 
{ 
    [TestMethod] 
    public void TestSomething() 
    { 
     //Arrange 
     var appliance = new ApplianceViewModel(); //This would fail to construct 

    } 
} 

。基本的には、クラスが一定で、カーネルに直接アクセスするのが悪いということです。

しかし、viewmodelのコンストラクタを変更して、リストを初期化できる、つまりテスト可能にする方法はありますか?

ありがとうございます。

+4

[service locator anti pattern](http://blog.ploeh)ではなくIoCをDIで使用する方がよいでしょうか。dk/2010/02/03/ServiceLocatorisanAnti-Pattern /)? – YuvShap

+0

@SomeUser:はい、私はServiceLocatorのパターンが私を傷つけるものだと思いますが、私の心の質問はそれを書き直す方法でした。それから私は[この解決策](http://stackoverflow.com/questions/7816769/injecting-an-ienumerable-into-a-constructor-with-a-ninject-factory-method)を見つけました。私はこの問題を解決すると思います私は持っています。 – Marshal

答えて

0

オブジェクトのリストを返す別のインターフェイス(IHardwareStuff)を使用できます。 IHardwareStuffは、ViewModelのコンストラクタに引数として渡されます。これは依存性注入コンテナによって解決され、必要に応じてテスト実装を入力することができます。

は、この分離を行うことにより、あなたは 値オブジェクトサービスオブジェクトにあなたのオブジェクトを分割します。 newを実行して具体的な値を渡して最初に作成したもの。後者は依存性注入コンテナによって作成され、コンストラクタとして渡された具体的な値はありません。

両方のオブジェクトに対して単体テストを書くことはできません。

0

コンストラクタが何もしない場合、検証や変数の代入を行うとよいでしょう。

私はApplianceViewModelのコンストラクタにリストHardwareItemsを注入することをお勧めします。

1

しかし、私はどのように私はリストを初期化することができます、つまりそれをテスト可能にするために、私のビューモデルのコンストラクタを変更するだろうか?

既存の定数とビューモデルを注入でき、実行時にそう
public class ApplianceViewModel : IAppliance 
{ 
    private List<IHardware> HardwareItems {get; set;} 

    public ApplianceViewModel(IHardware hardware1, Hardware hardware2) 
    { 
     HardwareItems = new List<IHardware>(); 
     var hardware1 = hardware1; 
     var hardware2 = hardware2; 

     HardwareItems.Add(hardware1); 
     HardwareItems.Add(hardware2);   
    } 
} 

あなたはIHardwareインタフェースの実装でそれを注入

var appliance = new ApplianceViewModel(Constants.Kernel.Get<IHardware>(), Constants.Kernel.Get<IHardware>()); 

...とのあなたあなたが同じインタフェースの他の実装で渡すユニットテストプロジェクト:

IHardware testHardware = new TestHardware(); 
var appliance = new ApplianceViewModel(testHardware, testHardware); 

この「TestHardware」クラスは、テストに合格するように実装する必要があります。 mockingフレームワークを使用すると便利です。この詳細については、次のリンクを参照してください。http://codetunnel.io/what-is-a-mocking-framework-why-is-it-useful/

+0

精巧に感謝します。私は何をすべきか分かっていたが、それをどうやって行うべきか分かっていなかった。私は[これは](http://stackoverflow.com/questions/7816769/injecting-an-ienumerable-into-a-constructor-with-a-ninject-factory-method)私が必要とするものを私に取ると思います。 – Marshal

関連する問題