A partire da questo concetto:
1) Inizia con il comportamento che desideri. Scrivi un test per questo. Vedi test fallito.
2) Scrivi abbastanza codice per far passare il test. Vedi tutti i test superati.
3) Cerca il codice ridondante / sciatto -> refactor. Vedi i test ancora superati. Vai a 1
Quindi su # 1, diciamo che vuoi creare un nuovo comando (sto estendendo a come funzionerebbe il comando, quindi abbi pazienza con me). (Inoltre, sarò un po 'pragmatico piuttosto che estremo TDD)
Il nuovo comando si chiama MakeMyLunch, quindi devi prima creare un test per istanziarlo e ottenere il nome del comando:
@Test
public void instantiateMakeMyLunch() {
ICommand command = new MakeMyLunchCommand();
assertEquals("makeMyLunch",command.getCommandName());
}
Questo fallisce, costringendoti a creare la nuova classe di comando e far sì che ritorni il suo nome (il purista direbbe che si tratta di due round di TDD, non 1). Quindi crei la classe e la fai implementare l'interfaccia ICommand, incluso restituire il nome del comando. L'esecuzione di tutti i test ora mostra tutti i passaggi, quindi si procede alla ricerca di opportunità di refactoring. Probabilmente nessuno.
Quindi, dopo, vuoi che venga eseguito. Quindi devi chiederti: come faccio a sapere che "MakeMyLunch" ha "preparato il mio pranzo" con successo. Cosa cambia nel sistema a causa di questa operazione? Posso fare un test per questo?
Supponiamo che sia facile testare per:
@Test
public void checkThatMakeMyLunchIsSuccessful() {
ICommand command = new MakeMyLunchCommand();
command.execute();
assertTrue( Lunch.isReady() );
}
Altre volte, questo è più difficile e ciò che vuoi veramente fare è testare le responsabilità del soggetto sotto test (MakeMyLunchCommand). Forse la responsabilità di MakeMyLunchCommand è di interagire con Frigo e Microonde. Quindi per testarlo puoi usare un finto frigorifero e un finto microonde. [due framework simulati di esempio sono Mockito e nMock o guarda qui .]
Nel qual caso dovresti fare qualcosa come il seguente pseudo codice:
@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 );
}
Il purista dice di testare la responsabilità della tua classe - le sue interazioni con altre classi (il comando ha aperto il frigorifero e acceso il forno a microonde?).
Il pragmatico dice test per un gruppo di classi e test per il risultato (il tuo pranzo è pronto?).
Trova il giusto equilibrio adatto al tuo sistema.
(Nota: considera che forse sei arrivato alla struttura della tua interfaccia troppo presto. Forse puoi lasciarlo evolvere mentre scrivi i test e le implementazioni delle tue unità, e nel passaggio 3 "noti" l'opportunità di interfaccia comune).