TDD: verifica del coordinamento di grafici di oggetti forniti da librerie di terze parti

4

Sembra che ci siano molte risorse su come simulare il codice di terze parti quando quel codice è semplice. A JSONRequest , ecc. Ma quando si utilizza una libreria di terze parti che richiede la configurazione di un grafo di oggetti relativamente complesso, ad esempio tre o più classi, le risorse sembrano esaurirsi.

Ad esempio, supponi che ti sia stata data un'interfaccia repository, IRepository , e ora hai il compito di testare e implementare un repository concreto usando Acme Inc nuovo AcmeBase , quindi inizi a lavorare creando la tua nuova AcmeRepository class.

L'ORM di AcmeBase richiede la configurazione di un grafo di oggetti relativamente complesso per poterlo utilizzare. Gli oggetti nel grafico - benché organizzati bene - sono tutti abbastanza strettamente accoppiati:

C'è il Context , il FetchRequest , il Store , il StoreCoordinator , poi ci sono tutti gli oggetti AcmeRecord proprietari che, ovviamente, non sono oggetti dati puri. Potresti rompere il problema in più parti. Dì, avvolgi le classi Context , FetchRequest e AcmeRecord , ma come fai a prendere in giro un'operazione come execute(request: FetchRequest) -> Set<AcmeRecord> sulla nostra classe Context ? Tutto ciò che l'isolamento sembrerebbe ostacolare il design della struttura, creare molto più lavoro e aumentare ironicamente l'area di superficie per i bug.

Come fai a testare questo tipo di coordinamento complesso se non possiedi le classi di terze parti?

Sembra che creare un wrapper per la classe ogni che costituisce il grafico sia eccessivo. Ma come puoi verificare che il grafico sia stato istanziato ed è gestito come ti aspetti?

    
posta Tricky 14.08.2017 - 19:07
fonte

3 risposte

3

La complessità della libreria è irrilevante. Ciò che conta è quanto strettamente ti sei unito alla biblioteca. Se ti accoppi liberamente, puoi prenderlo in giro semplicemente controllando gli input e memorizzando i risultati nella cache.

Questo funziona ma devi essere disposto a creare un design che consenta di funzionare. Rendere semplici le cose complicate non è facile. È un lavoro.

Non pensarci nemmeno come a prendere in giro la libreria. Hai dei bisogni che la biblioteca può incontrare. Mock tutto ciò che potrebbe soddisfare tali esigenze. Non prendere in giro ciò di cui non hai bisogno.

    
risposta data 14.08.2017 - 20:14
fonte
3

Ok, quindi AcmeRepository conterrà un codice di database reale e la logica di business è già stata disgiunta dal database da IRepository . Per testare questa implementazione concreta, non ha senso "prendersi gioco di qualcosa dentro AcmeRepository away" - si vuole testare "la cosa reale", e se si è usato correttamente l'API del database Acme. .

Quindi dimenticatevi di "unit test" in senso stretto qui, o che un test unitario in tutte le circostanze non deve fare affidamento su nessun altro componente. Se vuoi sviluppare la cosa usando TDD, devi prima configurare un database di test con gli elementi di base necessari per eseguire AcmeRepository e scrivere i test su questo DB. Se sei fortunato, AcmeBase ti consentirà di utilizzare una configurazione leggera e veloce in memoria per questo, o fornirà una "modalità di test" in cui convalida tutte le chiamate API molto rapidamente senza troppo sovraccarico. Se sei sfortunato, è un mostro come Oracle [metti qui il tuo famoso DB pesante], e il tuo test funzionerà molto lentamente mentre la gestione del database di test ti farà venire il mal di testa.

Non penso che ci sia una scorciatoia per questo, per le API di terze parti, il TDD può ancora essere applicato, ma solo nella misura supportata dall'API di terze parti.

Martin Fowler ha scritto un bel articolo sui test unitari di termine, e chiama il tipo di test necessari qui " test di unità socievoli ", al contrario di" test di unità solitari ". Questo articolo descrive anche le due "scuole di pensiero", i "classicisti" ei "mockisti", dove questi ultimi insistono che i "solitari test unitari" sono "l'unico vero tipo di test unitari", mentre i primi vedono più valore in "test di unità socievoli".

    
risposta data 17.08.2017 - 21:27
fonte
0

Non prendere in giro ciò che non possiedi . Avvolgilo invece in una delle tue classi e prendi in giro il wrapper nei tuoi test unitari. Prova la libreria di terze parti attraverso il wrapper, se possibile, senza fare il mocking di nulla, in una suite di test separata, più a lungo se necessario.

Si scopre che hai già quel wrapper - è AcmeRepository . Esistono numerosi modi per testare il codice di accesso ai dati, sia con una versione in memoria del database che con quella reale. Ma in pratica si limitano a impostare i dati di test nel DB, chiamare uno dei metodi di AcmeRepository e verificare cosa ne viene fuori o cosa entra nel database. Può essere lento e incline a testare problemi di sovrapposizione, ma il trucco è isolare quella bestia dalla normale suite di test unitari e ideare una specifica politica di test (frequenza di esecuzione della suite di test, criticità, ecc.).

    
risposta data 18.08.2017 - 15:47
fonte