Write Test di unità per applicazioni con database pesante? [duplicare]

5

Attualmente sto sviluppando un'applicazione web basata su Spring, in cui quasi ogni operazione crea / aggiorna / elimina qualcosa nel database. La logica in gran parte riguarda il controllo delle condizioni in modo da poter creare / aggiornare i record nel database o no.

Il motivo per cui voglio provare il test unitario è che spesso incontriamo errori di regressione quando vengono richieste modifiche o refactoring. La maggior parte dei bug proviene da modifiche al database, quando non rifletto pienamente tali modifiche nel codice. Ho un po 'di esperienza nello sviluppo web ora, ma sembra che non sia abbastanza per fermarli.

Il mio controller / servizio non è in realtà troppo complesso. Prendo solo l'oggetto vincolante inviato da HttpRequest, controlla la condizione & registrare in DB. A volte il sistema deve leggere il database, estrarre alcuni record e amp; manipolarli, quindi aggiorna altri record. Gran parte dello sforzo di codifica si trova anche sull'interfaccia (HTML / CSS / Javascript).

Sto esaminando il test di unità e ho sentito che quando si tratta di operazioni sul database, non è più un test di unità, poiché il test sarà lento. È vero? In modo che se il mio progetto è pesantemente funzionante con il database, non dovrei usare unit test?

Ho anche sentito parlare di DBUnit & alcuni database in memoria che possono accelerare il test. Dovrei usarli? E come posso scrivere un buon test unitario per il funzionamento del database?

    
posta Hoàng Long 12.01.2012 - 04:13
fonte

2 risposte

5

Probabilmente dovresti avere test di unità e test di integrazione . Nei test di unità, si testano ad esempio i controller / servizi in isolamento. Per ottenere ciò, è possibile utilizzare ad esempio un framework di simulazione come Easymock o Mockito per tagliare la dipendenza dal database.

I tuoi test di integrazione dovrebbero andare per tutto il tempo, dai tuoi controllori / servizi al database. È possibile scrivere i test di integrazione con la stessa struttura di base dei test di integrazione (JUnit o TestNG per denominare i più popolari). Mi piace personalmente DBUnit per prepopolare un database e verificare lo stato del database dopo il test. L'utilizzo di un database IMO in memoria dipende strongmente dal livello di persistenza. Se si utilizza ad esempio un framework JPA che genera le proprie query, mi piace avere un db in memoria. Se scrivi le tue query SQL, può essere più difficile utilizzare un altro DB rispetto al tuo target di produzione poiché non puoi essere sicuro che la sintassi sarà equivalente, quindi un test di integrazione per es. un database H2 in memoria non significa necessariamente che la sintassi funzioni con DB2. Ciò diventa ancora più problematico se usi le stored procedure.

Un buon test di integrazione funziona da solo, il che significa che è necessario impostare il database prima di ogni test per evitare la dipendenza tra i test. Non vuoi che il successo dei tuoi test dipenda dall'ordine in cui sono eseguiti. Dopo aver eseguito le tue operazioni, dovresti usare qualche tipo di asserzione per verificare se lo stato del database è conforme alle tue aspettative. DBUnit ad esempio ha le proprie asserzioni per il confronto di dataset o tabelle.

    
risposta data 12.01.2012 - 07:17
fonte
1

I also heard about DBUnit & some in-memory database which can quicken the test. Should I use them?

Sì.

And how I can write good unit test for database operation?

Nello stesso modo in cui scrivi qualsiasi altro test unitario.

Osservi l'interfaccia definita per la tua classe (o metodo) e scrivi un test che dimostra che funziona quando deve funzionare e si interrompe quando si suppone che si rompa.

La tua configurazione potrebbe essere alquanto complessa perché devi inserire righe nel database che corrispondono ai requisiti del tuo test unitario.

    
risposta data 12.01.2012 - 12:04
fonte

Leggi altre domande sui tag