Metodi di unit test che chiamano i fornitori di servizi web


10

Ho una lezione con un metodo pubblico Send()e alcuni metodi privati. Chiama un paio di servizi web ed elabora la risposta. L'elaborazione avviene in metodi privati.

Voglio testare l'unità il codice. La mia comprensione è che i test unitari dovrebbero testare il mio codice in modo isolato (ovvero simulare le risposte dei fornitori).

Credo anche che i metodi privati ​​non debbano essere sottoposti a test unitari Ma se provo semplicemente il metodo Send () il mio codice non viene testato in modo isolato e dipende dalla risposta del fornitore.

Devo quindi rendere pubblici i miei metodi privati ​​in modo da poterli testare con risposte simulate? Sembra una cattiva pratica dato che solo la classe dovrebbe chiamarli.

Mi scuso se è una domanda di base, sono abbastanza nuovo per i test unitari.

Sto usando c # e VS2010


Se non collaudi un metodo privato, come fai a sapere se funziona?
Bryan Oakley,

1
@BryanOakley non devi sapere che un metodo privato funziona, è privato. Sai che funziona perché i metodi pubblici che lo chiamano superano i loro test.
StuperUser,

@Bryan Oakley dai un'occhiata al link
Tom Squires,

Ciao Tom, ho aggiornato il link per renderlo più prominente e fare in modo che il testo del link rifletta il suo obiettivo. Sentiti libero di tornare indietro.
StuperUser,

Risposte:


18

È necessario separare il codice relativo ai servizi Web (ovvero l'invio e la ricezione di dati) dal codice che elabora i risultati. Spostare quest'ultimo codice in una classe distinta, rendendo pubblici i metodi necessari. Quindi puoi facilmente testare l'unità della logica di elaborazione, in isolamento dalle dipendenze esterne.

In questo modo, rendi anche il tuo codice conforme al Principio di responsabilità singola . Come regola generale, sentire la necessità di testare metodi privati ​​è spesso un'indicazione che la classe ha troppe responsabilità, quindi dovrebbe essere riformulata in più classi.


3

Penso che un test con tali dipendenze ( chiamando i servizi web dei fornitori ) sia un test di integrazione piuttosto che un test unitario.


3

Come altri hanno affermato, se i test unitari hanno dipendenze esterne come i servizi Web o le chiamate al database, NON sono affatto test unitari, sono test di integrazione.

I test unitari reali possono essere eseguiti indipendentemente dai componenti esterni oltre al componente che devono testare e devono essere ripetibili indipendentemente dall'ambiente. Se i servizi Web esterni non funzionano, il test dell'unità non dovrebbe fallire.

Ci aggiriamo usando un Mocking Framework. Gli oggetti finti ci consentono di creare un finto di un componente in modo che il componente nel nostro test unit utilizzi questi oggetti finti invece di quelli reali. Possiamo iniettare oggetti finti nel componente testabile e specificare quali argomenti ci aspettiamo, cosa vorremmo che ritornasse quando viene chiamato, anche quale eccezione vorremmo che generasse. Consiglio vivamente di leggere di più sull'argomento poiché migliorerà l'affidabilità e l'indipendenza dei test unitari.

Per un buon post su diversi framework di derisione C #, vedere il seguente thread SO:

/programming/37359/what-c-mocking-framework-to-use

EDIT: per i palesemente sensibile, possederò che ho trascurato di menzionare DbUnit o altri strumenti transazionali che possono eseguire il rollback delle modifiche al database alla fine del test. Questi sono anche ripetibili e possono essere indipendenti dall'ambiente con i dati di test generati, quindi in questo caso non è necessario un Mocking Framework.


Qualcuno può spiegare il downvote? Non ho eseguito il ripping su database PHP, ROR, NoSQL, Javascript sul server, prodotti Apple o qualsiasi altra tendenza favolosa, ma ho ANCORA ottenuto un downvote drive-by comunque: S
maple_shaft

Immagino che a qualcuno non piacesse che i loro test unitari venissero chiamati "non test unitari" (non ero io) :)
Daniel B
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.