2016-03-23 21 views
0

自分のプロジェクトの1つにビジネスロジックコンポーネントをユニットテストしたいと思います。単体テストでEntity Frameworkコンテキストを模擬するか代替するか?

BL:

public class CommunicationService 
{ 
    IContext context; 

    public CommunicationService() 
    { 
     var kernel = new StandardKernel(new NinjectConfig()); 
     context = kernel.Get<IContext>(); 
    } 

    // This creates a file 
    public void SomeMethodThatUsesIContext() { ... } 
} 

NinjectConfig:

class NinjectConfig : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IContext>().To<CommunicationDbContext>(); 
    } 
} 

ユニットテスト:

class FakeNinjectConfig : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IContext>().To<FakeDbContext>(); 
    } 
} 

[TestMethod] 
public void ScheduleTransportOrder_1() 
{ 
    communicationService = new CommunicationService(); 
    communicationService.SomeMethodThatUsesIContext(); 
    Assert.IsTrue(...) // file should be created. 
} 

私はユニットテストのプロジェクト内の別のNinjectの設定を持っています

そして、私はIContextのこの実装を単体テストで使用します。しかし、それはやはり元のCommunicationDbContext実装を使用しています。私は、ここにもう1つのninject設定があると、それがカーネルにロードされると信じていましたが、今私は何か誤解していました。あなたはそれを手伝ってもらえますか?

+1

問題は本当にあなたがやっているという事実に由来 '新しいStandardKernel(新NinjectConfig())IContextを注入することができます'あなたの' CommunicationService'コンストラクタで。あなたのロジックが分かりませんが、実際には、現在のコードで 'CommunicationService'に偽の' IContext'を提供することはできません。私はコンストラクタインジェクションをNinjectを使って見て、 'IContext'を' CommunicationService'に自動的に注入すると、あなたのテストで虚偽のインスタンスを提供することができます。 –

答えて

2

コンストラクタにFakeNinjectConfigの代わりにNinjectConfigを使用してカーネルを作成するのが問題です。

public class CommunicationService 
{ 
    IContext context; 

    public CommunicationService() 
    { 
     var kernel = new StandardKernel(new NinjectConfig()); 
     context = kernel.Get<IContext>(); 
    } 

簡単な方法:

あなたはNinjectModuleまたはStandardKernelを注入する新しいコンストラクタを作成することができます。

public CommunicationService (StandardKernel kernel) 
{ 
    context = kernel.Get<IContext>(); 
} 

public CommunicationService(NinjectModule injectModule):this (new StandardKernel(injectModule)) 
{ 
    context = kernel.Get<IContext>(); 
} 

public CommunicationService():this (new NinjectConfig()) 
{} 

そして、テストでは、FakeNinjectConfigでコンストラクタを呼び出すことができます。

[TestMethod] 
public void ScheduleTransportOrder_1() 
{ 
    communicationService = new CommunicationService(new FakeNinjectConfig()); 
    communicationService.SomeMethodThatUsesIContext(); 
    Assert.IsTrue(...) // file should be created. 
} 

それとも

[TestMethod] 
public void ScheduleTransportOrder_1() 
{ 
    communicationService = new CommunicationService(new StandardKernel(new FakeNinjectConfig())); 
    communicationService.SomeMethodThatUsesIContext(); 
    Assert.IsTrue(...) // file should be created. 
} 

適切な方法:

しかし、私の視点では、あなたが依存関係としてIContextを追加し、CommunicationServiceを解決IContextを注入しなければなりません。その後、

public class CommunicationService 
{ 
    IContext context; 

    public CommunicationService(IContext _context) 
    { 
     context = _context; 
    } 

そして、あなたはカーネルのGet方法の代わりに、new演算子を使用する必要がありますCommunicationServiceを作成します。たとえば、代わりに communicationService = new CommunicationService()のあなたはcommunicationService = Kernel.Get<CommunicationService>();

[TestMethod] 
public void ScheduleTransportOrder_1() 
{ 
    var testKernel = new StandardKernel(new FakeNinjectConfig()); 
    communicationService = testKernel.Get<CommunicationService>(); 
    communicationService.SomeMethodThatUsesIContext(); 
    Assert.IsTrue(...) // file should be created. 
} 

を使用する必要がありますまたはあなたが直接

[TestMethod] 
public void ScheduleTransportOrder_1() 
{ 
    communicationService = new CommunicationService(new FakeDbContext()); 
    communicationService.SomeMethodThatUsesIContext(); 
    Assert.IsTrue(...) // file should be created. 
} 
関連する問題