Test con Spring MVC, Spring Data JPA e Mockito

Esistono moltissimi tool per gestire i casi di test e ovviamente questo per lo sviluppatore è positivo perchè ci permette di avere tanti diversi approcci per testare un’applicazione. Nell’articolo di oggi vedremo uno dei possibili approcci per realizzare dei test su applicazioni basate principalmente sui framework messi a disposizione da Spring.

La nostra applicazione tipo sarà suddivisa in maniera abbastanza classica in 3 layer: Controller, Service e DAO. L’applicazione d’esempio mostra una pagina di login e permette banalmente di verificare le credenziali, senza avere troppe funzionalità che tanto non sono utili per i fini dell’articolo. Vediamo quindi come sia possibile testare i diversi layer applicativi

 

DAO

Per la parte di accesso ai dati è stato utilizzato Spring Data JPA. L’unica tabella mappata dall’applicativo è UTENTE e il relativo entity si chiama UtenteEntity. Di seguito viene riportato il repository che si occupa di gestire l’entità relativa agli utenti

Oltre a questo repository, che ci permette di avere le funzionalità CRUD su UtenteEntity, abbiamo anche una classe che ci permette di definire ulteriori metodi da esporre

In questo caso l’unico metodo aggiuntivo è listaUtentiRangeDataRegistrazione che ritorna appunto una lista di utenti i quali si sono registrati nell’intervallo di tempo specificato come parametro. Per effettuare il test della parte DAO possiamo utilizzare un database H2 che possiamo far partire attraverso la seguente classe di configurazione

In questo modo abbiamo a disposizione un database H2 per i nostri test. Dobbiamo però anche creare le tabelle (e volendo popolarle) e questo possiamo farlo utilizzando una configurazione Spring che richiamerà l’esecuzione di alcuni script

In questa configurazione abbiamo richiamato 2 script per creare/popolare le tabelle e inoltre abbiamo istanziato tutti i bean che servono a Spring Data JPA per poter funzionare. Possiamo quindi ora passare al vero e proprio caso di test. Utilizzando un framework che ci fornisce già i metodi CRUD non sarebbe tanto sensato testarli, quindi verrà definito solo il caso di test relativo al metodo che recupera gli utenti in base all’intervallo di registrazione.

Il caso di test riporta l’annotation @RunWith(SpringJUnit4ClassRunner.class) che ci permette di utilizzare delle feature aggiuntive a JUnit per effettuare i test, come potete trovare in maniera dettagliata nella documentazione ufficiale. Nel metodo setupData, annotato con @Before che quindi verrà eseguito prima dell’esecuzione del test, predisponiamo i dati che ci serviranno per questo e li salviamo sul database.

Abbiamo già visto che tramite gli script possiamo popolare la nostra base dati, ma dipende da come vogliamo gestire i dati di test. Una soluzione potrebbe essere quella di popolare tramite script le tabelle parametriche o comunque di amministrazione della nostra applicazione e poi nel singolo caso di test popolare quello di cui abbiamo bisogno. Nel metodo di test testListaUtentiRangeDataRegistrazione andiamo quindi a richiamare il repository invocando il metodo da testare ed effettuiamo delle verifiche tramite dei metodi d’utilità di JUnit assertEquals e assertNotNull.

 

Service

Lo strato Service della nostra applicazione è la classe LoginServiceImpl che si occupa di verificare le credenziali dell’utente

Il test che si deve occupare di questo componente si troverà nella classe LoginServiceTest e dovrà testare LoginServiceImpl senza occuparsi dello strato DAO. Per questo motivo utilizzeremo Mockito, framework opensource che ci permette di creare dei Mock, ovvero degli oggetti che simulano il comportamento di altri, all’interno dei nostri casi di test.

Quindi nel caso dello strato Service utilizzeremo una configurazione classica Spring per istanziare qualsiasi cosa ci possa servire e una classe di configurazione come la seguente

Come potete vedere per UtenteRepository creiamo un Mock utilizzando Mockito, al quale passiamo semplicemente la classe di cui si deve occupare. All’interno del setup del caso di test invece andremo a definire come si deve comportare questo Mock quando viene richiamato

Anche qui abbiamo un metodo annotato con @Before che prepara i dati e in questo caso dice al Mock di UtenteRepository che quando verrà richiamato il suo metodo findOne, con il parametro String “utente” allora dovrà restituire l’entity utente appena costruita. I due test poi che sono presenti richiamano il metodo autentica di LoginService, prima con le credenziali corrette e poi con quelle sbagliate.

 

Controller

Vediamo infine come effettuare il test dello strato relativo ai Controller. In questo caso utilizzeremo Mockito per simulare lo strato Service e Spring MVC Test che fornisce una serie di utility che permettono di effettuare i test in maniera abbastanza agevole. Il Controller che dobbiamo testare mostra prima la pagina di login e poi richiama il metodo autentica di LoginService per controllare l’autenticazione.

Il test in questo caso utilizzerà una configurazione simile a quella vista per lo strato Service, solo che i Mock adesso saranno i Service richiamati e le implementazioni da testare i Controller.

Quindi vediamo la classe di test LoginControllerTest che in fase di setup definisce un utente di prova e le risposte che dovrà fornire il metodo autentica di LoginService attraverso Mockito

I metodi di test utilizzano la classe MockMvc per descrivere il comportamento che dovrà avere il nostro caso di test. Utilizzando il pattern Builder vediamo che definiamo il path e il metodo con cui fare la richiesta,

successivamente i parametri

e cosa ci aspettiamo dal risultato

 

Conclusioni

Quella che abbiamo visto in questo articolo è solo una possibile configurazione che si può utilizzare per scrivere dei test unitari per la nostra applicazione. Inoltre cercando nelle librerie di test possiamo trovare molte altre cose interessanti, come Selenium per i test d’integrazione (che abbiamo visto in questo e quest’altro articolo ), Cucumber per definire dei test Behavior Driven e tante altre interessanti iniziative. Di seguito trovate il progetto d’esempio dell’articolo presente su GitHub

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *