Un esempio di un caso di errore che dovresti prefet catturare, è che l'oggetto in prova utilizza un livello di memorizzazione nella cache, ma non riesce a mantenere i dati come richiesto. Quindi, se interroghi l'oggetto, dirai "sì, ho il nuovo nome e indirizzo", ma vuoi che il test fallisca perché non ha effettivamente fatto ciò che avrebbe dovuto.
In alternativa (e trascurando la violazione di responsabilità singola), supponiamo che sia necessario mantenere una versione con codifica UTF-8 della stringa in un campo orientato ai byte, ma in realtà persiste Shift JIS. Qualche altro componente leggerà il database e si aspetta di vedere UTF-8, quindi il requisito. Quindi il round-trip attraverso questo oggetto riporterà il nome e l'indirizzo corretti perché verrà convertito da Shift JIS, ma l'errore non viene rilevato dal test. Si spera che venga rilevato da alcuni test di integrazione successivi, ma l'intero punto dei test unitari è quello di individuare i problemi in anticipo e sapere esattamente quale componente è responsabile.
If one of them is not doing what it's supposed to, then its own test case will fail and we can fix it and run the test battery again.
Non puoi supporre questo, perché se non stai attento scrivi una serie di test reciprocamente dipendenti. Il "salva?" test chiama il metodo di salvataggio che sta testando e quindi il metodo di caricamento per confermarlo. Il "carica?" test chiama il metodo di salvataggio per configurare il dispositivo di prova e quindi il metodo di caricamento che sta testando per verificare il risultato. Entrambi i test si basano sulla correttezza del metodo che non testano, il che significa che nessuno dei due test effettivamente la correttezza del metodo che sta testando.
L'indizio che ci sia un problema qui, è che due test che presumibilmente stanno testando unità differenti in realtà fanno la stessa cosa . Entrambi chiamano un setter seguito da un getter, quindi controllano che il risultato sia il valore originale. Ma volevi testare che il setter persista sui dati, non che la coppia setter / getter lavori insieme. Quindi sai che qualcosa non va, devi solo capire cosa e correggere i test.
Se il tuo codice è ben progettato per il test delle unità, allora ci sono almeno due modi per testare se i dati sono stati effettivamente mantenuti correttamente dal metodo sotto test:
-
prendi in giro l'interfaccia del database e chiedi al tuo mock di registrare il fatto che sono state chiamate le funzioni appropriate, con i valori attesi. Questo verifica che il metodo faccia quello che dovrebbe, ed è il test unitario classico.
-
passa a un vero database con esattamente la stessa intenzione , per registrare se i dati sono stati persi o meno correttamente. Ma piuttosto che avere una funzione derisoria che dice semplicemente "sì, ho i dati giusti", il tuo test ritorna direttamente dal database e conferma che è corretto. Questo potrebbe non essere il test più puro possibile, perché un intero motore di database è una grande cosa da usare per scrivere un finto glorificato, con più possibilità di trascurare qualche sottigliezza che fa passare un test anche se qualcosa è sbagliato (quindi per esempio non dovrei usare la stessa connessione al database per leggere come è stato usato per scrivere, perché potrei vedere una transazione senza commit). Ma mette alla prova la cosa giusta, e almeno sai che precisamente implementa l'intera interfaccia del database senza dover scrivere alcun codice di simulazione!
Quindi è un semplice dettaglio dell'implementazione del test se leggo i dati dal database di test da JDBC o se sto prendendo in giro il database. In ogni caso, il punto è che posso testare l'unità isolandola meglio di me se permetto che si possa cospirare con altri metodi errati sulla stessa classe per guardare bene anche quando qualcosa non va. Quindi voglio usare qualsiasi mezzo conveniente per verificare che i dati corretti siano persistenti, diversi da fidati del componente il cui metodo sto testando.
Se il tuo codice è non ben progettato per il test delle unità, allora potresti non avere scelta, perché l'oggetto il cui metodo vuoi testare potrebbe non accettare il database come dipendenza iniettata. Nel qual caso la discussione sul modo migliore per isolare l'unità in prova, cambia in una discussione su quanto vicino è possibile arrivare ad isolare l'unità sotto test. La conclusione è la stessa, però. Se riesci a evitare cospirazioni tra unità difettose, lo fai, in base al tempo disponibile e a qualsiasi altra cosa tu pensi che sarebbe più efficace nel trovare errori nel codice.