Spring JdbcTemplate Unit Testing

1. Общ преглед

Spring JdbcTemplate е мощен инструмент за разработчиците да се съсредоточат върху писането на SQL заявки и извличане на резултати. Той се свързва към базата данни и изпълнява директно SQL заявки.

Следователно можем да използваме тестове за интеграция, за да сме сигурни, че можем правилно да изтегляме данни от базата данни. Също така можем да напишем модулни тестове, за да проверим коректността на свързаните с тях функционалности.

В този урок ще покажем как да тествате код на JdbcTemplate .

2. JdbcTemplate и изпълняващи се заявки

Първо, нека започнем с клас на обект за достъп до данни (DAO), който използва 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); } }

Ние впръскваме обект DataSource в класа EmployeeDAO . След това създаваме обекта JdbcTemplate в метода на задаване . Също така използваме JdbcTemplate в примерен метод getCountOfEfficiees ().

Има два начина за модулни тестови методи, които използват JdbcTemplate .

Можем да използваме база данни в паметта като базата данни H2 като източник на данни за тестване . Въпреки това, в реални приложения SQL заявката може да има сложни взаимоотношения и трябва да създадем сложни скриптове за настройка, за да тестваме SQL изразите.

Друга възможност е да се подиграем с обекта JdbcTemplate, за да тестваме функционалността на метода.

3.Единичен тест с база данни H2

Можем да създадем източник на данни, който се свързва с базата данни H2 и да го инжектира в класа 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()); }

В този тест първо изграждаме източник на данни в базата данни H2. По време на изграждането изпълняваме schema.sql, за да създадем таблицата EMPLOYEE :

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

Също така стартираме test-data.sql, за да добавим тестови данни в таблицата:

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

След това можем да инжектираме този източник на данни в класа EmployeeDAO и да тестваме метода getCountOfEfficiees в базата данни H2 в паметта.

4.Единичен тест с фиктивен обект

Можем да се подиграем с обекта JdbcTemplate, така че да не се налага да изпълняваме SQL израза в база данни:

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

В този единичен тест първо декларираме фиктивен обект JdbcTemplate с анотацията @Mock . След това го инжектираме в обекта EmployeeDAO, използвайки ReflectionTestUtils. Също така използваме помощната програма Mockito , за да се подиграем с резултата от връщането на заявката JdbcTemplate . Това ни позволява да тестваме функционалността на метода getCountOfEfficiees , без да се свързваме с база данни.

Използваме точно съвпадение на низа на оператор SQL, когато се подиграваме с заявката JdbcTemplate . В реални приложения можем да създаваме сложни SQL низове и е трудно да се направи точно съвпадение. Следователно можем да използваме метода anyString () , за да заобиколим проверката на низа:

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

5. Spring Boot @JdbcTest

И накрая, ако използваме Пролет Boot, има анотация можем да използваме, за да работят поетапно тест с база данни H2 и JdbcTemplate боб: @JdbcTest .

Нека създадем тестов клас с тази анотация:

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

Също така можем да отбележим наличието на анотацията @Sql, която ни позволява да посочим SQL файловете, които да се изпълняват преди теста.

6. Заключение

В този урок показахме множество начини за единичен тест JdbcTemplate.

Както винаги, изходният код на статията е достъпен в GitHub.