Aggiornamento: Vedi this question too.
posso rispondere solo alcune parti qui:
va bene a rompere tutte le dipendenze che utilizzano le interfacce solo per fare una classe verificabile? Implica un sovraccarico significativo in fase di esecuzione a causa di molte chiamate virtuali anziché di semplici richiami di metodi.
Se la tua performance ne risentirebbe troppo, no (punto di riferimento!). Se il tuo sviluppo soffre troppo, no (stima sforzo extra). Se sembra che non importi molto e aiuti a lungo termine e ti aiuti con la qualità, sì.
È sempre possibile "amico" le classi di test o un oggetto TestAccessor tramite il quale i test possono indagare su di esso. Ciò evita di rendere tutto facilmente disparabile solo per i test. (sembra un bel po 'di lavoro.)
La progettazione di interfacce testabili non è facile. A volte devi aggiungere alcuni metodi extra che accedono ai componenti interni solo per il test. Ti fa rabbrividire un po 'ma è bello avere e il più delle volte quelle funzioni sono utili anche nell'applicazione reale, prima o poi.
Se eseguo un refactoring, si verifica molto spesso che devo ripetere completamente il test dell'unità a causa di enormi modifiche logiche. Il mio codice cambia molto spesso cambia la logica fondamentale dell'elaborazione dei dati. Non vedo un modo per scrivere test unitari che non devono cambiare in un grande refactoring.
I grandi rifattori per definizione cambiano molto, compresi i test. Sii felice di averli come testeranno la roba anche dopo il refactoring.
Se si impiegano più tempo per il refactoring di nuove funzionalità, forse dovresti considerare di pensare un po 'di più prima della codifica per trovare interfacce migliori in grado di resistere a più cambiamenti. Inoltre, scrivere dei test unitari prima che le interfacce siano stabili è un dolore, indipendentemente da quello che fai.
Più codice hai contro un'interfaccia che cambia molto, più codice dovrai cambiare ogni volta. Penso che il tuo problema stia lì. Sono riuscito a disporre di interfacce sufficientemente stabili nella maggior parte dei casi e a rifattare le parti solo di tanto in tanto.
Spero che aiuti.
Non è che non penso prima della codifica. Molto spesso i requisiti cambiano dopo che il cliente ha visto l'implementazione iniziale di una nuova funzionalità. Un altro motivo è che a volte è necessario eseguire un'implementazione rapida e sporca per motivi di marketing. In questo caso non mi preoccupo dei test unitari, ma a volte l'hack veloce e sporco diventa la cosa reale a causa di un calendario serrato. Non è facile rendere questo pasticcio più tardi. – frast
Scusa, non intendevo implicare esattamente quello. ;) So che a volte la vita reale è difficile da lavorare. Quick'n dirty ha un debito, un test mancante, un necessario refactoring/cleanup o di solito entrambi. Si paga prima in contanti (lavoro appropriato) o si paga in affitto dopo (pulizia). Non andare in giro. È difficile lavorare in condizioni in cui non puoi influenzarlo. (Ci sono stato ...) – Macke