Spring JdbcTemplate Unit Testing

1. Panoramica

Spring JdbcTemplate è un potente strumento che consente agli sviluppatori di concentrarsi sulla scrittura di query SQL e sull'estrazione dei risultati. Si connette al database back-end ed esegue direttamente le query SQL.

Pertanto, possiamo utilizzare i test di integrazione per assicurarci di poter estrarre correttamente i dati dal database. Inoltre, possiamo scrivere unit test per verificare la correttezza delle relative funzionalità.

In questo tutorial, mostreremo come eseguire un test unitario del codice JdbcTemplate .

2. JdbcTemplate e query in esecuzione

In primo luogo, iniziamo con una classe DAO (Data Access Object) che utilizza JdbcTemplate :

public class EmployeeDAO { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); } public int getCountOfEmployees() { return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM EMPLOYEE", Integer.class); } }

Inseriamo in dipendenza un oggetto DataSource nella classe EmployeeDAO . Quindi, creiamo l' oggetto JdbcTemplate nel metodo setter. Inoltre, utilizziamo JdbcTemplate in un metodo di esempio getCountOfEmployees ().

Esistono due modi per eseguire i metodi di unit test che utilizzano JdbcTemplate .

Possiamo usare un database in memoria come il database H2 come fonte di dati per i test . Tuttavia, nelle applicazioni del mondo reale, la query SQL potrebbe avere relazioni complicate e abbiamo bisogno di creare script di configurazione complessi per testare le istruzioni SQL.

In alternativa, possiamo anche deridere l' oggetto JdbcTemplate per testare la funzionalità del metodo.

3.Test unitario con database H2

Possiamo creare un'origine dati che si connetta al database H2 e iniettarla nella classe EmployeeDAO :

@Test public void whenInjectInMemoryDataSource_thenReturnCorrectEmployeeCount() { DataSource dataSource = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) .addScript("classpath:jdbc/schema.sql") .addScript("classpath:jdbc/test-data.sql") .build(); EmployeeDAO employeeDAO = new EmployeeDAO(); employeeDAO.setDataSource(dataSource); assertEquals(4, employeeDAO.getCountOfEmployees()); }

In questo test, costruiamo prima un'origine dati sul database H2. Durante la costruzione, eseguiamo schema.sql per creare la tabella EMPLOYEE :

CREATE TABLE EMPLOYEE ( ID int NOT NULL PRIMARY KEY, FIRST_NAME varchar(255), LAST_NAME varchar(255), ADDRESS varchar(255) );

Inoltre, eseguiamo test-data.sql per aggiungere dati di test nella tabella:

INSERT INTO EMPLOYEE VALUES (1, 'James', 'Gosling', 'Canada'); INSERT INTO EMPLOYEE VALUES (2, 'Donald', 'Knuth', 'USA'); INSERT INTO EMPLOYEE VALUES (3, 'Linus', 'Torvalds', 'Finland'); INSERT INTO EMPLOYEE VALUES (4, 'Dennis', 'Ritchie', 'USA');

Quindi, possiamo inserire questa origine dati nella classe EmployeeDAO e testare il metodo getCountOfEmployees sul database H2 in memoria.

4.Test unitario con oggetto fittizio

Possiamo deridere l' oggetto JdbcTemplate in modo da non dover eseguire l'istruzione SQL su un database:

public class EmployeeDAOUnitTest { @Mock JdbcTemplate jdbcTemplate; @Test public void whenMockJdbcTemplate_thenReturnCorrectEmployeeCount() { EmployeeDAO employeeDAO = new EmployeeDAO(); ReflectionTestUtils.setField(employeeDAO, "jdbcTemplate", jdbcTemplate); Mockito.when(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM EMPLOYEE", Integer.class)) .thenReturn(4); assertEquals(4, employeeDAO.getCountOfEmployees()); } }

In questo test unitario, dichiariamo prima un oggetto JdbcTemplate fittizio con l' annotazione @Mock . Quindi lo iniettiamo nell'oggetto EmployeeDAO usando ReflectionTestUtils. Inoltre, utilizziamo l' utilità Mockito per simulare il risultato restituito dalla query JdbcTemplate . Ciò ci consente di testare la funzionalità del metodo getCountOfEmployees senza connettersi a un database.

Usiamo una corrispondenza esatta sulla stringa dell'istruzione SQL quando deridiamo la query JdbcTemplate . Nelle applicazioni del mondo reale, possiamo creare stringhe SQL complesse ed è difficile ottenere una corrispondenza esatta. Pertanto, possiamo anche utilizzare il metodo anyString () per bypassare il controllo delle stringhe:

Mockito.when(jdbcTemplate.queryForObject(Mockito.anyString(), Mockito.eq(Integer.class))) .thenReturn(3); assertEquals(3, employeeDAO.getCountOfEmployees());

5. Spring Boot @JdbcTest

Infine, se stiamo usando Primavera di avvio, c'è un'annotazione che possiamo usare per creare un semplice test con un database di H2 e un JdbcTemplate fagiolo: @JdbcTest .

Creiamo una classe di test con questa annotazione:

@JdbcTest @Sql({"schema.sql", "test-data.sql"}) class EmployeeDAOIntegrationTest { @Autowired private JdbcTemplate jdbcTemplate; @Test void whenInjectInMemoryDataSource_thenReturnCorrectEmployeeCount() { EmployeeDAO employeeDAO = new EmployeeDAO(); employeeDAO.setJdbcTemplate(jdbcTemplate); assertEquals(4, employeeDAO.getCountOfEmployees()); } }

Possiamo anche notare la presenza dell'annotazione @Sql che ci permette di specificare i file SQL da eseguire prima del test.

6. Conclusione

In questo tutorial, abbiamo mostrato diversi modi per testare l'unità JdbcTemplate.

Come sempre, il codice sorgente dell'articolo è disponibile su GitHub.