Beginnen Sie mit diesem Konzept:
1) Beginnen Sie mit dem gewünschten Verhalten. Schreiben Sie einen Test dafür. Siehe Test fehlgeschlagen.
2) Schreiben Sie genügend Code, um den Test zu bestehen. Alle Tests bestehen.
3) Suchen Sie nach redundantem / schlampigem Code -> Refactor. Siehe Tests noch bestanden. Gehe zu 1
Nehmen wir also auf # 1 an, Sie möchten einen neuen Befehl erstellen (ich strecke mich danach, wie der Befehl funktionieren würde, also nehmen Sie ihn mit). (Außerdem bin ich eher ein bisschen pragmatisch als extrem TDD)
Der neue Befehl heißt MakeMyLunch. Sie erstellen also zuerst einen Test, um ihn zu instanziieren und den Befehlsnamen abzurufen:
@Test
public void instantiateMakeMyLunch() {
ICommand command = new MakeMyLunchCommand();
assertEquals("makeMyLunch",command.getCommandName());
}
Dies schlägt fehl und zwingt Sie, die neue Befehlsklasse zu erstellen und ihren Namen zurückzugeben (Purist würde sagen, dies sind zwei Runden TDD, nicht 1). Sie erstellen also die Klasse und lassen sie die ICommand-Schnittstelle implementieren, einschließlich der Rückgabe des Befehlsnamens. Wenn Sie jetzt alle Tests ausführen, werden alle Tests angezeigt. Suchen Sie daher nach Refactoring-Möglichkeiten. Wahrscheinlich keine.
Als nächstes möchten Sie, dass es execute implementiert. Sie müssen sich also fragen: Woher weiß ich, dass "MakeMyLunch" erfolgreich "mein Mittagessen zubereitet" hat? Welche Änderungen im System aufgrund dieser Operation? Kann ich das testen?
Angenommen, es ist einfach zu testen auf:
@Test
public void checkThatMakeMyLunchIsSuccessful() {
ICommand command = new MakeMyLunchCommand();
command.execute();
assertTrue( Lunch.isReady() );
}
In anderen Fällen ist dies schwieriger, und Sie möchten wirklich die Verantwortlichkeiten des zu testenden Probanden testen (MakeMyLunchCommand). Möglicherweise liegt die Verantwortung von MakeMyLunchCommand in der Interaktion mit Kühlschrank und Mikrowelle. Um es zu testen, können Sie einen Scheinkühlschrank und eine Scheinmikrowelle verwenden. [Zwei Beispiel-Mock-Frameworks sind Mockito und nMock oder schauen Sie hier .]
In diesem Fall würden Sie so etwas wie den folgenden Pseudocode tun:
@Test
public void checkThatMakeMyLunchIsSuccessful() {
Fridge mockFridge = mock(Fridge);
Microwave mockMicrowave = mock(Microwave);
ICommand command = new MakeMyLunchCommand( mockFridge, mockMicrowave );
command.execute();
mockFramework.assertCalled( mockFridge.removeFood );
mockFramework.assertCalled( microwave.turnon );
}
Der Purist sagt, testen Sie die Verantwortung Ihrer Klasse - ihre Interaktionen mit anderen Klassen (hat der Befehl den Kühlschrank geöffnet und die Mikrowelle eingeschaltet?).
Der Pragmatiker sagt Test für eine Gruppe von Klassen und Test für das Ergebnis (ist Ihr Mittagessen fertig?).
Finden Sie die richtige Balance, die für Ihr System funktioniert.
(Hinweis: Bedenken Sie, dass Sie möglicherweise zu früh zu Ihrer Schnittstellenstruktur gelangt sind. Vielleicht können Sie dies beim Schreiben Ihrer Komponententests und Implementierungen weiterentwickeln, und in Schritt 3 "bemerken" Sie die allgemeine Schnittstellenmöglichkeit.)