Test unitaire Spring JdbcTemplate

1. Vue d'ensemble

Spring JdbcTemplate est un outil puissant permettant aux développeurs de se concentrer sur l'écriture de requêtes SQL et l'extraction des résultats. Il se connecte à la base de données principale et exécute directement les requêtes SQL.

Par conséquent, nous pouvons utiliser des tests d'intégration pour nous assurer que nous pouvons extraire correctement les données de la base de données. De plus, nous pouvons écrire des tests unitaires pour vérifier l'exactitude des fonctionnalités associées.

Dans ce didacticiel, nous montrerons comment tester un code JdbcTemplate .

2. JdbcTemplate et requêtes en cours d'exécution

Tout d'abord, commençons par une classe d'objet d'accès aux données (DAO) qui utilise 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); } }

Nous injectons en dépendance un objet DataSource dans la classe EmployeeDAO . Ensuite, nous créons l' objet JdbcTemplate dans la méthode setter. De plus, nous utilisons JdbcTemplate dans un exemple de méthode getCountOfEmployees ().

Il existe deux méthodes de test unitaire utilisant JdbcTemplate .

Nous pouvons utiliser une base de données en mémoire telle que la base de données H2 comme source de données pour les tests . Cependant, dans les applications du monde réel, la requête SQL peut avoir des relations complexes et nous devons créer des scripts de configuration complexes pour tester les instructions SQL.

Alternativement, nous pouvons également nous moquer de l' objet JdbcTemplate pour tester la fonctionnalité de la méthode.

3.Test unitaire avec base de données H2

Nous pouvons créer une source de données qui se connecte à la base de données H2 et l'injecter dans la 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()); }

Dans ce test, nous construisons d'abord une source de données sur la base de données H2. Lors de la construction, nous exécutons schema.sql pour créer la table EMPLOYEE :

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

De plus, nous exécutons test-data.sql pour ajouter des données de test dans la table:

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');

Ensuite, nous pouvons injecter cette source de données dans la classe EmployeeDAO et tester la méthode getCountOfEmployees sur la base de données H2 en mémoire.

4.Test unitaire avec objet simulé

Nous pouvons nous moquer de l' objet JdbcTemplate afin de ne pas avoir besoin d'exécuter l'instruction SQL sur une base de données:

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()); } }

Dans ce test unitaire, nous déclarons d'abord un objet JdbcTemplate fictif avec l' annotation @Mock . Ensuite, nous l'injectons à l' objet EmployeeDAO à l' aide de ReflectionTestUtils. De plus, nous utilisons l' utilitaire Mockito pour simuler le résultat de retour de la requête JdbcTemplate . Cela nous permet de tester la fonctionnalité de la méthode getCountOfEmployees sans nous connecter à une base de données.

Nous utilisons une correspondance exacte sur la chaîne de l'instruction SQL lorsque nous nous moquons de la requête JdbcTemplate . Dans les applications du monde réel, nous pouvons créer des chaînes SQL complexes et il est difficile de faire une correspondance exacte. Par conséquent, nous pouvons également utiliser la méthode anyString () pour contourner la vérification de la chaîne:

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

5. Spring Boot @JdbcTest

Enfin, si nous utilisons Spring Boot, il y a une annotation que nous pouvons utiliser pour amorcer un test avec une base de données H2 et un JdbcTemplate haricot: @JdbcTest .

Créons une classe de test avec cette annotation:

@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()); } }

On peut également noter la présence de l' annotation @Sql qui nous permet de spécifier les fichiers SQL à exécuter avant le test.

6. Conclusion

Dans ce didacticiel, nous avons montré plusieurs méthodes de test unitaire JdbcTemplate.

Comme toujours, le code source de l'article est disponible à l'adresse over sur GitHub.