Ich wollte mir beibringen, den TDD-Ansatz zu verwenden, und ich hatte ein Projekt, an dem ich schon eine Weile arbeiten wollte. Es war kein großes Projekt, also dachte ich, es wäre ein guter Kandidat für TDD. Ich habe jedoch das Gefühl, dass etwas schief gelaufen ist. Lassen Sie mich ein Beispiel geben:
Auf hoher Ebene ist mein Projekt ein Add-In für Microsoft OneNote, mit dem ich Projekte einfacher nachverfolgen und verwalten kann. Jetzt wollte ich auch die Geschäftslogik dafür so weit wie möglich von OneNote entkoppelt halten, falls ich beschloss, eines Tages meinen eigenen benutzerdefinierten Speicher und ein Back-End zu erstellen.
Zuerst begann ich mit einem Akzeptanztest für einfache Wörter, um zu skizzieren, was meine erste Funktion tun sollte. Es sieht ungefähr so aus (der Kürze halber dumm stellen):
- Benutzer klickt auf Projekt erstellen
- Benutzer gibt den Titel des Projekts ein
- Stellen Sie sicher, dass das Projekt korrekt erstellt wurde
Überspringe die UI-Sachen und mache eine Zwischenplanung. Ich komme zu meinem ersten Unit-Test:
[TestMethod]
public void CreateProject_BasicParameters_ProjectIsValid()
{
var testController = new Controller();
Project newProject = testController(A.Dummy<String>());
Assert.IsNotNull(newProject);
}
So weit, ist es gut. Rot, Grün, Refactor, etc. Okay, jetzt muss es wirklich etwas sparen. Hier ein paar Schritte rauszuschneiden, macht mich fertig.
[TestMethod]
public void CreateProject_BasicParameters_ProjectMatchesExpected()
{
var fakeDataStore = A.Fake<IDataStore>();
var testController = new Controller(fakeDataStore);
String expectedTitle = fixture.Create<String>("Title");
Project newProject = testController(expectedTitle);
Assert.AreEqual(expectedTitle, newProject.Title);
}
Ich fühle mich zu diesem Zeitpunkt immer noch gut. Ich habe noch keinen konkreten Datenspeicher, aber ich habe die Benutzeroberfläche so erstellt, wie ich es mir vorgestellt habe.
Ich werde hier ein paar Schritte überspringen, weil dieser Beitrag lang genug wird, aber ich habe ähnliche Prozesse befolgt und komme schließlich zu diesem Test für meinen Datenspeicher:
[TestMethod]
public void SaveNewProject_BasicParameters_RequestsNewPage()
{
/* snip init code */
testDataStore.SaveNewProject(A.Dummy<IProject>());
A.CallTo(() => oneNoteInterop.SavePage()).MustHaveHappened();
}
Dies war gut, bis ich versuchte, es umzusetzen:
public String SaveNewProject(IProject project)
{
Page projectPage = oneNoteInterop.CreatePage(...);
}
Und da ist das Problem, wo das "..." ist. Ich erkenne jetzt an DIESEM Punkt, dass CreatePage eine Abschnitts-ID erfordert. Ich habe das damals nicht gemerkt, als ich auf Controllerebene nachgedacht habe, weil ich mich nur mit dem Testen der für den Controller relevanten Bits befasst habe. Den ganzen Weg hier unten ist mir jedoch klar, dass ich den Benutzer nach einem Speicherort für das Projekt fragen muss. Jetzt muss ich dem Datenspeicher eine Standort-ID hinzufügen, dann eine zum Projekt hinzufügen, dann eine zum Controller hinzufügen und zu ALLEN Tests hinzufügen, die bereits für all diese Dinge geschrieben wurden. Es ist sehr schnell langweilig geworden und ich kann nicht anders, als das Gefühl zu haben, ich hätte es schneller bemerkt, wenn ich das Design im Voraus entworfen hätte, anstatt es während des TDD-Prozesses entwerfen zu lassen.
Kann mir bitte jemand erklären, ob ich etwas falsch gemacht habe? Gibt es überhaupt eine Möglichkeit, diese Art des Refactorings zu vermeiden? Oder ist das üblich? Wenn es üblich ist, gibt es Möglichkeiten, es schmerzloser zu machen?
Vielen Dank an alle!