Począwszy od tej koncepcji:
1) Zacznij od pożądanego zachowania. Napisz na to test. Zobacz test zakończony niepowodzeniem.
2) Napisz wystarczającą ilość kodu, aby pomyślnie przejść test. Zobacz wszystkie testy zaliczone.
3) Poszukaj kodu nadmiarowego / niechlujstwa -> refaktora. Zobacz, testy wciąż się kończą. Idź 1
Tak więc w punkcie 1 powiedzmy, że chcesz utworzyć nowe polecenie (rozciągam się na sposób działania polecenia, więc trzymaj się mnie). (Będę też bardziej pragmatyczny niż ekstremalny TDD)
Nowe polecenie nazywa się MakeMyLunch, więc najpierw tworzysz test, aby go utworzyć i uzyskać nazwę polecenia:
@Test
public void instantiateMakeMyLunch() {
ICommand command = new MakeMyLunchCommand();
assertEquals("makeMyLunch",command.getCommandName());
}
To się nie udaje, zmuszając cię do utworzenia nowej klasy poleceń i zwrócenia jej nazwy (purysta powiedziałby, że to dwie rundy TDD, a nie 1). Tworzysz klasę i implementujesz interfejs ICommand, w tym zwracając nazwę polecenia. Uruchomienie wszystkich testów pokazuje teraz wszystkie zaliczenia, więc zaczynasz szukać możliwości refaktoryzacji. Prawdopodobnie żaden.
Następnie chcesz, aby implementacja wykonała. Musisz więc zapytać: skąd mam wiedzieć, że „MakeMyLunch” z powodzeniem „zrobił mój lunch”. Jakie zmiany w systemie spowodowane tą operacją? Czy mogę to przetestować?
Załóżmy, że łatwo jest przetestować:
@Test
public void checkThatMakeMyLunchIsSuccessful() {
ICommand command = new MakeMyLunchCommand();
command.execute();
assertTrue( Lunch.isReady() );
}
Innym razem jest to trudniejsze i naprawdę chcesz przetestować obowiązki badanego obiektu (MakeMyLunchCommand). Być może obowiązkiem MakeMyLunchCommand jest interakcja z lodówką i kuchenką mikrofalową. Aby to przetestować, możesz użyć fałszywej lodówki i fałszywej kuchenki mikrofalowej. [dwie przykładowe frameworki to Mockito i nMock lub spójrz tutaj .]
W takim przypadku zrobiłbyś coś takiego jak następujący pseudo kod:
@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 );
}
Purysta mówi, aby przetestować odpowiedzialność swojej klasy - jej interakcje z innymi klasami (czy polecenie otworzyło lodówkę i włączyło kuchenkę mikrofalową?).
Pragmatysta mówi: przetestuj grupę zajęć i sprawdź wynik (czy lunch jest gotowy?).
Znajdź odpowiednią równowagę, która działa dla twojego systemu.
(Uwaga: pamiętaj, że być może doszedłeś do struktury interfejsu zbyt wcześnie. Być może możesz to ewoluować, pisząc testy jednostkowe i implementacje, aw kroku # 3 „zauważysz” powszechną możliwość interfejsu).