Ihre Erfahrungen Mine sehr ähnlich ist, ausgehend. Während ich auf TDD verkauft werde und nichts anders machen würde, verstehe ich Ihre Verwirrung. Es ist wichtig, daran zu denken, dass TDD eine Designphilosophie ist. Davon abgesehen denke ich, dass ich Ihnen helfen kann, einige Ihrer Frustrationen zu klären.
Sie zunächst darüber nachzudenken, was Sie versuchen, nicht auf individuellem Testniveau zu erreichen, aber was Sie zu tun versuchen. Wenn Ihre Aufgabe (User Story) darin besteht, einige Anmeldeinformationen zu erfassen und den aktuellen Benutzer basierend auf diesen Anmeldeinformationen zu authentifizieren, starten Sie von dort aus und arbeiten sich nach unten. Sie scheinen in dieser Richtung zu gehen, nur zu den nächsten Schritten stecken
Wenn auf einem individuellen Test arbeiten, denken Sie an es in Bezug auf expected behavior anstatt nur einige Ein- und Ausgänge zu überprüfen. Stellen Sie sich diese Komponente vor und schreiben Sie einfach eine Codezeile so, wie Sie sie schreiben möchten. Lassen Sie diesen Teil helfen, die Schnittstelle/den Vertrag Ihres Dienstes zu steuern. Sie müssen sich die Frage stellen: "Wenn ich diese Methode nennen würde, wie würde ich wissen, dass sie funktioniert hat? Was würde ich davon erwarten?" Dies wird bestimmen, welche Art von Behauptungen Sie machen müssen.
Bestimmen Sie, was Ihre externen Abhängigkeiten sind, und utilize abstractions instead (Abhängigkeit Inversion-Prinzip). Wenn diese Abhängigkeiten etwas sind, was Sie als Teil Ihrer Verhaltensüberprüfung interessieren, dann verwenden Sie dependency injection, so dass Sie einen mock in Ihrem Test verwenden können.
Immer, immer, folgen Sie immer dieser Reihenfolge [Schreiben Sie Ihren Test, beobachten Sie es scheitern, Code zu übergeben, Refactor]. LERNEN SIE VON MEINEN FEHLERN !!! Vertrau mir, das ist nicht verhandelbar. Andernfalls können Sie TDD Ihre Probleme vorwerfen, wenn es nicht ordnungsgemäß eingesetzt wird.
Ok, also das alles zusammen mit Ihrem Beispiel setzen, und einige schön test cases from lance zur Verfügung gestellt, könnten wir so etwas tun:
[Test]
public void ShouldAuthenticateValidUser()
{
IMyMockDa mockDa = new MockDataAccess();
var service = new AuthenticationService(mockDa);
mockDa.AddUser("Name", "Password");
Assert.IsTrue(service.DoLogin("Name", "Password"));
//Ensure data access layer was used
Assert.IsTrue(mockDa.GetUserFromDBWasCalled);
}
[Test]
public void ShouldNotAuthenticateUserWithInvalidPassword()
{
IMyMockDa mockDa = new MockDataAccess();
var service = new AuthenticationService(mockDa);
mockDa.AddUser("Name", "Password");
Assert.IsFalse(service.DoLogin("Name", "BadPassword"));
//Ensure data access layer was used
Assert.IsTrue(mockDa.GetUserFromDBWasCalled);
}
Ok, so gibt es eine Menge los dort, und vielleicht viel zu erforschen. Sie können jedoch beginnen zu sehen, wie es möglich ist, gründliche Tests mit besserem Design durchzuführen. In den obigen Beispielen ist es wichtig zu beachten, dass das Mock-Objekt benutzerdefiniert gewürfelt wird, aber Sie müssen nicht durch all diese Schmerzen gehen. Es gibt viele Mocking Frameworks da draußen. Zum Beispiel mit RhinoMocks, würde Ihr Test wie folgt aussehen:
[Test]
public void ShouldAuthenticateValidUser()
{
var mockRepo = new MockRepository();
var mockDa = mockRepo.DynamicMock<IMyMockDa>();
var service = new AuthenticationService(mockDa);
using(mockRepo.Record())
{
//I realize this is a terrible method and should not exist if you
// care about security, but for demonstration purposes...
Expect.Call(mockDa.GetPassword("User")).Return("Password");
}
using(mockRepo.Playback())
{
Assert.IsTrue(service.DoLogin("User", "Password"));
}
}
Dinge die manuelle Art und Weise zu tun, zum ersten Mal verwendet, so dass Sie die Konzepte verstehen und dann weiterziehen, um ein Framework. Wütend! Viele Informationen, aber wie Sie sehen können, ist TDD eine komplette Design-Philosophie. Es wird jedoch sauberer Code, besseres Design und weniger Fehler führen.
Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu schreiben! Ich schätze es sehr. Du hast viele gute Sachen gesagt und es wird wahrscheinlich eine Weile dauern, bis ich alles verstanden habe. Du hast recht, dass ich mich daran gewöhnen muss, anders zu denken, wenn ich TDD mache. Hoffentlich wird meine Verwirrung eines Tages vorüber sein, aber das wird nur Zeit brauchen. Danke noch einmal! – CalebHC
Es hat lange gedauert, bis ich diesen "Ah Ha" -Moment hatte, aber jetzt bin ich total bekehrt. Ich würde Sie ermutigen, einen anderen SO-Beitrag zu lesen, den ich über TDD machte: http://stackoverflow.com/questions/106800/unit-testing-guidelines/106813#106813 – Josh
Das wackelige Rendering, das Sie sahen, ist ein bekannter Fehler mit alten Antworten - Sie können dies für jede Antwort (nicht nur für Ihre eigene) korrigieren, indem Sie eine Bearbeitung einreichen, wodurch die Antwort erneut gerendert wird. Dies erklärt auch, warum es gut aussieht, wenn Sie den Editor zum ersten Mal aufrufen. Ich habe die Formatierung hier geändert, aber Sie können auch eine Stub-Bearbeitung senden und sie rückgängig machen, und die Antwort wird trotzdem erneut gerendert. – BoltClock