Per fare semplici test, il mocking del livello di accesso al database è perfettamente accettabile. Chiama getName()
, chiama il DAO che è stato deriso e restituisce "John" come nome e "Smith" come cognome, li assembla e tutto è perfetto. Non c'è bisogno di testare in pratica un database lì.
Le cose diventano un po 'più quando la logica diventa un po' più complessa. Cosa succede se hai un metodo "createOrUpdateUser (...)". Se prendi in giro il database, puoi verificare che un determinato metodo sia stato chiamato una volta con un determinato parametro quando la simulazione non restituisce alcun oggetto e un metodo diverso viene richiamato sul database quando restituisce un oggetto esistente. Questo inizia ad arrivare a quella linea fuzzy dove potrebbe essere più facile (specialmente se fosse già lì) per far ruotare un database specializzato nella memoria e testare quel codice con dati preconfigurati.
In un codice reale su cui ho lavorato (punto di vendita), avevamo un metodo resumeSuspededTransaction(...)
. Ciò estrarrà la transazione dal database in un oggetto (e i suoi componenti) e aggiornerà il database. L'abbiamo preso in giro e un bug si nasconde nel codice da qualche parte con la serializzazione e la deserializzazione dei dati che vanno nel database (abbiamo cambiato un tipo che è stato serializzato in modo diverso sul database).
Il mock non ci ha mostrato il bug perché stava restituendo il suo percorso felice: serializza la transazione, la memorizza nella simulazione, deserializza la simulazione, verifica che siano uguali. Tuttavia, quando serializzi un oggetto con uno zero iniziale nel database, questo è stato rilasciato e quindi ricombinato su una stringa senza zeri. Abbiamo rilevato il bug senza il database attraverso la risoluzione dei problemi (non era difficile da individuare una volta che sapevamo che era lì).
Successivamente, abbiamo inserito un database e ci siamo resi conto che il bug non avrebbe mai superato quel test di junit se stessimo andando in un database in memoria.
Nei database di memoria hanno i vantaggi:
- possono essere convertiti rapidamente (senza bisogno di un DBA per configurare account, tabelle e simili) per il test
- i dati possono essere preconfigurati per quel test
- il test non ha bisogno di preoccuparsi di ripristinare il test una volta terminato
- ogni test ha il suo database di memoria in modo da non doversi preoccupare se due test sono eseguiti contemporaneamente
- possono essere eseguiti su sistemi che non hanno connettività con i veri database