Ho una classe che viene refactored in 1 classe principale e 2 classi più piccole. Le classi principali utilizzano il database (come fanno molte delle mie classi) e invia un'e-mail. Quindi la classe principale ha un IPersonRepository
e un IEmailRepository
iniettato che a sua volta invia alle 2 classi più piccole.
Ora voglio unit test della classe principale e ho imparato a non unittire il funzionamento interno della classe, perché dovremmo essere in grado di cambiare il funzionamento interno senza interrompere i test unitari.
Ma poiché la classe usa IPersonRepository
e e IEmailRepository
, DEVO specificare i risultati (fittizi / fittizi) per alcuni metodi per IPersonRepository
. La classe principale calcola alcuni dati basati su dati esistenti e li restituisce. Se voglio verificarlo, non vedo come posso scrivere un test senza specificare che IPersonRepository.GetSavingsByCustomerId
restituisce x. Ma poi il mio test unitario "conosce" i meccanismi interni, perché "sa" quali metodi deridere e quali no.
Come posso testare una classe che ha iniettato dipendenze, senza che il test sia a conoscenza degli interni?
sfondo:
Nella mia esperienza molti test come questo creano simulazioni per i repository e quindi forniscono i dati giusti per le simulazioni o test se durante l'esecuzione è stato chiamato un metodo specifico. In entrambi i casi, il test conosce gli interni.
Ora ho visto una presentazione sulla teoria (che ho sentito prima) che il test non dovrebbe conoscere l'implementazione. In primo luogo perché non esegue il test come funziona, ma anche perché quando si cambia ora l'attuazione tutti gli unit test falliscono perché sanno '' circa l'attuazione. Mentre mi piace l'idea che i test non siano consapevoli dell'implementazione, non so come realizzarlo.
IPersonRepository
oggetto, quell'interfaccia e tutti i metodi che descrive non sono più "interni", quindi non è davvero un problema del test. La tua vera domanda dovrebbe essere "come posso trasformare le classi in unità più piccole senza esporre troppo in pubblico". La risposta è "mantenere snelle quelle interfacce" (attenendosi al principio di seggregation dell'interfaccia, per esempio). Questo è il punto 2 di IMHO nella risposta di @ DavidArno (suppongo che non sia necessario che lo ripeta in un'altra risposta).