2016-06-02 6 views
2

Ich versuche immer noch, dem Pfad zu TDD zu folgen.Wie Sie TDD verwenden, wenn Ihre Methode für viele Aufgaben ausgelegt ist

Angenommen, ich habe einen SunSystemBroker ausgelöst, wenn eine Datei in einen freigegebenen Ordner hochgeladen wird. Dieser Broker wurde entwickelt, um diese Datei zu öffnen, Datensätze daraus zu extrahieren, verbundene Zahlungen in anderen Systemen zu finden und schließlich einen Workflow aufzurufen!

Wenn ich TDD folgen möchte, um die IBroker.Process() - Methode zu entwickeln, wie soll ich tun?

Hinweis: Broker sind unabhängige Assemblies, die von IBroker erben und von einer Konsolenanwendung geladen werden (wie Plugins).

Diese Konsole ist verantwortlich für die Auslösung jedes Brokers!

public interface IFileTriggeredBroker : IBroker 
{ 
    FileSystemTrigger Trigger { get; } 
    void Process(string file); 
} 

public class SunSystemPaymentBroker : IFileTriggeredBroker 
{ 
    private readonly IDbDatasourceFactory _hrdbFactory; 
    private readonly IExcelDatasourceFactory _xlFactory; 
    private readonly IK2DatasourceFactory _k2Factory; 
    private ILog _log; 

    public void Process(string file) 
    { 
     (...) 
     // _xlFactory.Create(file) > Extract 
     // _hrdbFactory.Create() > Find 
     // Compare Records 
     // _k2Factory.Create > Start 
    } 
} 

Jede Methode werden einzeln getestet.

Danke Seb

+0

Ich bin mir nicht sicher, ob das tatsächlich deine Frage ist oder nicht ...Aber ich hatte immer eine ähnliche Frage, wenn es um die Methoden geht, die "alles zusammenfügen". Wenn du die Methoden 'Foo',' Bar' und 'Baz' hast, die alle komplett eigenständig sind und etwas alleine machen, aber du musst sie für ein gewünschtes Verhalten zusammenketten, denke ich, dass" Verkettung "eine einzige ist Verantwortung, aber ich bin nie wirklich sicher, was ich diese Art von Klassen nennen soll. Und um sie zu testen, ist es einfach sicherzustellen, dass dieser "Chainer" alle benötigten Methoden von 'Foo',' Bar' und 'Baz' aufruft? – Kritner

Antwort

1

Vorausgesetzt, dass Sie jede Methode sagen:

_xlFactory.Create(file); 
_hrdbFactory.Create(); 

// Compare Records 
_k2Factory.Create(); 

einzeln getestet wird, gibt es sehr wenig Logik innerhalb Process(file) zu testen ist.

Wenn Sie so etwas wie Moq verwenden, können Sie überprüfen, ob die Anrufe auftreten:

// Arrange 
const string File = "file.xlsx"; 
var xlFactory = new Mock<IExcelDatasourceFactory>(); 
var hrbdFactory = new Mock<IDbDatasourceFactory>(); 
var k2Factory = new Mock<IK2DatasourceFactory>(); 

// Act 
var sut = new SunSystemPaymentBroker(xlFactory.Object, hrdbFactory.Object, k2Factory.Object); // I'm assuming you're using constructor injection 
sut.ProcessFile(File); 

// Assert 
xlFactory.Verify(m => m.Create(File), Times.Once); 
hrbdFactory.Verify(m => m.Create(), Times.Once); 
k2Factory.Verify(m => m.Create(), Times.Once); 

Der Kürze halber habe ich als einzelner Test dies getan, aber mit einem einzigen „assert“ in 3 Tests brechen (die verify Anrufe) ist realistischer. Für TDD würden Sie jeden Test schreiben, bevor Sie diese Methode innerhalb von Process(file) verkabeln.

Sie können auch mit einem größeren, Integrationsebene Tests aussehen wollen, wo Sie in konkreten Versionen von IExcelDatasourceFactory passieren, IK2DatasourceFactory, IDbDatasourceFactory und das System in mehr Tiefe ausüben.

Im Buch Growing Object-Oriented Software Guided by Tests, würde dies als Acceptance Test definiert werden, die vor der Arbeit begann geschrieben werden würden, und während die Funktion fehlschlägt in kleineren TDD Schleifen Funktionalität hinzugefügt, die in Richtung des Gesamtmerkmales arbeiten.

1

Sie haben zwei verschiedene Probleme:

1) ein Verfahren Code SOLID Stellen viel Aufgabe auszuführen ist so konzipiert, und das einzige Verantwortung Prinzip anzuwenden. Split mit Einzelverantwortlichkeitsmethoden: dh nur für eine Aufgabe verantwortlich.

2) Sie wollen eine Prozedur testen, die durch Nebenwirkung funktioniert (Umgebung ändern), keine reine Funktion. Also würde ich Ihnen empfehlen, Ihren Code in reine Funktionsaufrufe aufzuteilen (dh: keine Nebenwirkungen).

Lesen Sie auch https://msdn.microsoft.com/en-us/library/aa730844%28v=vs.80%29.aspx

+0

Alle meine Broker sind anders, weil ihr Ziel ist, verschiedene Aufgaben zu erfüllen. Die Konsolenanwendung kennt nur die Prozessmethode (über die Schnittstelle). Ich habe keine Möglichkeit zu wissen, dass ich Methode extract aufrufen muss, dann tue, dann drucke (...). Nur der Makler weiß das. – Seb