2015-04-07 19 views
5

Sembra che utilizzarli come metodo per verificare se il metodo in prova eseguito correttamente è controproducente perché porterà a test fragili. In altre parole stai legando il test all'implementazione. Quindi se successivamente vuoi cambiare l'implementazione dovrai anche cambiare il test. Sto facendo questa domanda perché sono stato addestrato ad usare sempre almeno uno di questi metodi in ogni test unitario e penso di aver appena avuto un'illuminazione che questa è in realtà una pessima pratica.Dovresti usare i metodi "Verifica" e "Verifica tutti" forniti da Moq nei tuoi Test di unità?

+0

Li considero anche cattive pratiche. Sono inutili e come dici tu: addirittura controproducenti. Non si ottiene assolutamente nulla da questo, ma le persone lo fanno fuori dall'automazione. È contrario all'idea di test unitari, quindi a meno che qualcun altro non possa fornire una buona ragione: non preoccuparti di loro. –

risposta

4

test

C'è un sacco di dibattito intorno alla fragilità dei mock nei test di unità e se sono una cosa buona o no Mock-based. Personalmente ritengo che sia un compromesso tra la manutenibilità e la robustezza.Più inserisci il tuo codice di produzione sotto unit test pressure, testandolo da solo con i mock, meno implementazioni possibili supereranno i test. Puoi così forzare il tuo codice di produzione in robustezza e buon design. D'altra parte, si lega a un'implementazione particolare e aumenta l'onere della manutenzione, poiché è necessario modificare più test non appena cambiano i dettagli dell'implementazione.

Il VerifyAll) sintassi (

E 'soprattutto una questione di gusto, ma trovo che VerifyAll() non è intenzione rivelatrice, vale a dire quando si legge una suite di test che ci si aspetta di ottenere una buona idea delle specifiche semplicemente osservando le asserzioni, e VerifyAll() non ha alcun significato. Anche quando scrivo test basati su simulazione, preferisco l'approccio Arrange Act Assert con specifici messaggi di errore. È più chiaro e meno "magico" di una telefonata allo VerifyAll() accattivante.

Utilizzando VerifyAll() in ogni metodo di test

E 'nel migliore e nel peggiore eccessivo causerà danni al vostro suite di test.

  • Come regola generale, un test di unità deve testare solo una cosa. La chiamata sistematica allo VerifyAll() in aggiunta alla normale asserzione porta confusione: se il test fallisce, non si può sapere con certezza cosa è andato storto.

  • Per quanto riguarda la leggibilità, si sta solo aggiungendo rumore a ciascuno dei test. È molto difficile solo leggendo un metodo di prova per risalire a ciò che significa realmente lo VerifyAll().

  • Generalmente si desidera scegliere dove applicare la pressione di progettazione sulle implementazioni con i mock e non applicarle ciecamente ovunque, perché c'è un prezzo di manutenzione.

Quindi, se avete davvero usare VerifyAll(), meglio scrivere test separati per esso IMO.

0

Il modo migliore è utilizzare AAA. Ma per le dipendenze esterne con tipo restituito vuoto (diciamo vuoto WriteData (Dati dati)), Verifica può essere utile (o Setup, quindi VerifyAll).

10

Prima di tutto, è importante capire che Verify metodi -Family sono lì per una ragione - che consentono di testare inosservabile comportamento del vostro sistema. Cosa intendo con questo? Considera un semplice esempio di generazione di applicazioni e invio di report. Molto probabilmente il tuo componente finale assomiglia a questo:

public void SendReport(DateTime reportDate, ReportType reportType) 
{ 
    var report = generator.GenerateReport(reportDate, reportType); 
    var reportAsPlainText = converter.ConvertReportToText(report); 
    reportSender.SendEmailToSubscribers(body: reportAsPlainText); 
} 

Come testare questo metodo? Non restituisce nulla, quindi non è possibile controllare i valori. Non cambia lo stato del sistema (come, sfogliando qualche bandiera), quindi non è possibile controllarlo. L'unico risultato visibile di SendReport viene chiamato è il fatto che il report è stato inviato tramite invocazione SendEmailToSubscribers. Questa è la principale responsabilità del metodo SendReport - e questo è ciò che i test unitari dovrebbero verificare.

Ovviamente, i test di unità non dovrebbero e non controlleranno se alcune e-mail sono state inviate o consegnate. Si verificherà una simulazione di reportSender. Ed è qui che utilizzi i metodi Verify. Per verificare che qualche chiamata a qualche finta abbia effettivamente avuto luogo.

Come nota finale, Roy Osherove nel suo libro Art Of Unit Testing (2nd edition) separa test di unità in tre categorie, a seconda ciò che può essere verificata: valore

  • ritorno del metodo (semplice, comune)
  • cambiamento in stato del sistema (semplice, raro)
  • chiamata al componente esterno (complessa, rara)

ultima categoria è wher e usi mazze e metodi Verify su di loro. Per gli altri due, sono sufficienti i mozzi (metodi Setup).

Quando il codice è stato progettato correttamente, tale test sarà (ultima categoria) in minoranza nella base di codice, da qualche parte nell'intervallo 5% - 10% (numero preso dal libro di Roy, in linea con le mie osservazioni).


: non osservabili come in quella chiamante non può facilmente verificare che cosa esattamente gionro dopo la chiamata.