Preferisci test all'interfaccia piuttosto che test sull'implementazione.
Comprendo che i metodi privati non sono verificabili
Questo dipende dal tuo ambiente di sviluppo, vedi sotto.
[metodi privati] non dovrebbero essere preoccupati perché l'API pubblica fornirà informazioni sufficienti per verificare l'integrità di un oggetto.
Esatto, TDD si concentra sul test dell'interfaccia.
I metodi privati sono dettagli di implementazione che potrebbero cambiare durante qualsiasi ciclo di rifattoriale. Dovrebbe essere possibile ricodificare senza modificare l'interfaccia o il comportamento della scatola nera . In effetti, ciò fa parte del vantaggio di TDD, la facilità con cui è possibile generare la sicurezza che le modifiche interne a una classe non influiranno sugli utenti di quella classe.
Bene, è possibile per me creare un oggetto che ha solo metodi privati e interagisce con altri oggetti ascoltando i loro eventi. Questo sarebbe molto incapsulato, ma completamente non verificabile.
Anche se la classe non ha metodi pubblici, i gestori di eventi sono l' interfaccia pubblica ed è contro quell'interfaccia pubblica che puoi testare.
Poiché gli eventi sono l'interfaccia, sono gli eventi che dovrai generare per testare quell'oggetto.
Cerca di usare oggetti finti come colla per il tuo sistema di test. Dovrebbe essere possibile creare un semplice oggetto simulato che genera un evento e rileva il conseguente cambio di stato (possibile tramite un altro oggetto simulato del ricevitore).
Inoltre, è considerata una cattiva pratica aggiungere metodi a scopo di test.
Assolutamente, dovresti essere molto cauto nell'esporre lo stato interno.
Questo significa che TDD è in contrasto con l'incapsulamento? Qual è il giusto equilibrio?
Assolutamente no.
TDD non dovrebbe cambiare l'implementazione delle tue classi se non forse per semplificarle (applicando YAGNI da un punto precedente).
Le migliori pratiche con TDD sono identiche alle migliori pratiche senza TDD, basta scoprire perché prima, perché stai usando l'interfaccia mentre la sviluppi.
Sono propenso a rendere pubblici la maggior parte o tutti i miei metodi ora ...
Questo sarebbe piuttosto buttare via il bambino con l'acqua del bagno.
Non è necessario rendere pubblici tutti i metodi in modo da poterli sviluppare in modo TDD. Vedi le mie note di seguito per vedere se i tuoi metodi privati non sono realmente verificabili.
Uno sguardo più dettagliato al test di metodi privati
Se devi assolutamente provare unitamente alcuni comportamenti privati di una classe, a seconda della lingua / ambiente, potresti avere tre opzioni:
- Inserisci i test nella classe che desideri testare.
- Inserisci i test in un altro file di classe / sorgente ed esponi i metodi privati che desideri testare come metodi pubblici.
- Utilizzare un ambiente di test che consenta di mantenere separato il codice di test e di produzione, consentendo comunque l'accesso al codice di test ai metodi privati del codice di produzione.
Ovviamente la terza opzione è di gran lunga la migliore.
1) Metti i test nella classe che vuoi testare (non ideale)
Memorizzare i casi di test nello stesso file di classe / sorgente del codice di produzione sotto test è l'opzione più semplice. Ma senza molte direttive o annotazioni pre-processore finirai con il tuo codice di test che gonfia inutilmente il tuo codice di produzione e, a seconda di come hai strutturato il tuo codice, potresti finire per esporre accidentalmente l'implementazione interna agli utenti di quel codice.
2) Esporre i metodi privati che si desidera testare come metodi pubblici (davvero non è una buona idea)
Come suggerito, questa è una pratica molto scadente, distrugge l'incapsulamento e esporrà l'implementazione interna agli utenti del codice.
3) Utilizzare un ambiente di test migliore (opzione migliore, se disponibile)
Nel mondo Eclipse, 3. può essere ottenuto usando frammenti . Nel mondo C #, potremmo usare classi parziali . Altre lingue / ambienti hanno spesso funzionalità simili, devi solo trovarle.
Supponendo ciecamente 1. o 2. sono le uniche opzioni che potrebbero comportare un software di produzione gonfio con codice di test o interfacce di classe sgradevoli che lavano la biancheria sporca in pubblico. * 8' )
- Tutto sommato, è molto meglio non testare contro l'implementazione privata.