La costruzione di mock complessi per unità test è un segno di cattiva architettura?

5

Il titolo è abbastanza autoesplicativo.

Per elaborare: sto attualmente aggiornando una suite di test unitari per un'applicazione che fa un uso pesante di Entity Framework. Ci colleghiamo a questo tramite una classica interfaccia di repository in modo che possa essere presa in giro.

Non stiamo facendo test prima (è un argomento completamente diverso, su cui non voglio che questa domanda degeneri). Piuttosto un "codice un po ', prova un po'" una sorta di approccio. Quindi non stiamo eseguendo il backfilling di un'intera applicazione con i test, neanche.

Apprezzo che un'intera suite di test per un'applicazione di questo tipo richieda probabilmente un finto repository molto complesso. Tuttavia, ho appena creato una nuova classe di test e il primo test ha richiesto un repository fittizio con circa 5 funzioni get / save del repository mocked out.

Era una funzione abbastanza semplice che veniva testata. La gamma di classi di simulazione era necessaria a causa delle operazioni eseguite nel costruttore della classe e simili.

Avendo fatto così mi è sembrato che a malapena sembrasse un'unità. E che potrebbe essere un segno il mio codice era troppo interdipendente. Quindi: sta creando un singolo test che richiede un finto complesso spesso un segno di scarsa architettura?

    
posta Matt Thrower 14.05.2015 - 10:57
fonte

1 risposta

7

Dovrò fare un paio di ipotesi qui

Si parla di EF quindi immagino che i mock in questione siano correlati al datalayer?

Dato che stai utilizzando EF, suppongo che il tuo repository presenti un IQueryable e che i tuoi Modelli costruiscano query al loro interno?

Questo ti porterebbe a dover creare una simulazione di dati che è coerente con le varie query eseguite dai tuoi Modelli, che immagino potrebbero finire per essere piuttosto complicate.

Penso che l'errore qui sia il repository interrogabile. La mia opinione è che i repository dovrebbero esporre metodi come

IEnumerable GetModelsByConditionXAndConditionY (var valueOfAParmeter)

anziché

IEnumerable GetModelsByQuery (Func SomeQueryFunction)

o

IQueryable GetModelsButDontReturnThemYetINeedToThink ()

Ciò consente di costruire una versione in memoria del database con dati di test coerenti, in quanto i modi in cui tali dati vengono restituiti sono noti al repository.

Qualsiasi classe di consumo può prendere il repository e ci si aspetta che funzioni correttamente senza l'impostazione specifica del modello dei dati.

Tendo anche a rendere questo repository finto come una sua classe piuttosto che usare un framework mock per configurarlo per unit test

Questo rende i tuoi test unitari piuttosto semplici dato che usano tutti gli stessi dati simulati e ti permette di iniettare gli stessi repository simulati nella tua vera app per i test dell'interfaccia utente ecc.

    
risposta data 14.05.2015 - 11:29
fonte

Leggi altre domande sui tag