2016-03-23 11 views
0

Ich möchte eine Business-Logik-Komponente in einem meiner Projekte Einheit testen.Wie kann Entity Framework-Kontext im Komponententest simuliert oder ersetzt werden?

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>(); 
    } 
} 

Unit-Test:

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

Ich habe eine andere Ninject config in dem Projekt Unit-Tests:

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

Und ich möchte diese Implementierung von IContext im Komponententest verwendet werden. Aber es verwendet immer noch die ursprüngliche CommunicationDbContext-Implementierung. Ich glaubte, wenn ich hier eine andere Ninject-Konfiguration habe, wird diese in den Kernel geladen, aber ich denke, jetzt habe ich etwas falsch verstanden. Könntest du mir dabei helfen?

+1

Das Problem injizieren wirklich ergibt sich aus der Tatsache, dass Sie 'neue StandardKernel (neu NinjectConfig()) tun 'in Ihrem 'CommunicationService'-Konstruktor. Ich bin mir nicht sicher, was Ihre Logik dafür ist, aber effektiv werden Sie nie in der Lage sein, einen verspotteten "IContext" zu "CommunicationService" mit dem aktuellen Code zu versehen. Ich würde Constructor Injection mit Ninject betrachten und den 'IContext' automatisch in' CommunicationService' einfügen lassen, was bedeutet, dass Sie eine gespottete Instanz in Ihrem Test bereitstellen können. –

Antwort

2

Das Problem ist, dass Sie den Kernel mit NinjectConfig statt FakeNinjectConfig in CommunicationService Konstruktor erstellen.

public class CommunicationService 
{ 
    IContext context; 

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

einfache Art und Weise:

Sie können einen neuen Konstruktor erstellen, um eine NinjectModule oder StandardKernel zu injizieren.

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()) 
{} 

Und im Test Sie den Konstruktor mit FakeNinjectConfig aufrufen können.

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

Oder

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

Richtige Art und Weise:

Aber in meiner Sicht, sollten Sie die IContext als Abhängigkeit hinzufügen und IContextCommunicationService Lösung injizieren.

public class CommunicationService 
{ 
    IContext context; 

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

Und dann, wenn Sie eine CommunicationService erstellen sollten Sie Get Methode der Kernel statt eines new Operator verwenden. Zum Beispiel sollte statt communicationService = new CommunicationService() Sie 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. 
} 

verwenden oder können Sie IContext direkt

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