Рубрики
Без рубрики

Модульное тестирование пружины JdbcTemplate

Узнайте несколько способов написания модульных тестов для кода, использующего JdbcTemplate

Автор оригинала: Gang Wu.

1. Обзор

Spring JdbcTemplate-это мощный инструмент для разработчиков, позволяющий сосредоточиться на написании SQL-запросов и извлечении результатов. Он подключается к внутренней базе данных и выполняет SQL-запросы напрямую.

Поэтому мы можем использовать интеграционные тесты, чтобы убедиться, что мы можем правильно извлекать данные из базы данных. Кроме того, мы можем писать модульные тесты для проверки правильности соответствующих функций.

В этом уроке мы покажем, как выполнить модульный тест JdbcTemplate code.

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 в методе setter. Кроме того, мы используем JdbcTemplate в примере метода get Count Of Employees().

Существует два способа модульного тестирования методов, которые используют 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 и протестировать метод get Count Of Employees в базе данных 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());
    }
}

В этом модульном тесте мы сначала объявляем объект mock JdbcTemplate с аннотацией @Mock . Затем мы вводим его в объект EmployeeDAO с помощью ReflectionTestUtils . Кроме того, мы используем утилиту Mockito для макетирования возвращаемого результата запроса JdbcTemplate . Это позволяет нам протестировать функциональность метода get Count Of Employees без подключения к базе данных.

Мы используем точное совпадение в строке оператора SQL, когда мы издеваемся над запросом JdbcTemplate . В реальных приложениях мы можем создавать сложные строки SQL, и точное совпадение трудно выполнить. Поэтому мы также можем использовать метод any String() для обхода проверки строки:

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

5. Пружинная загрузка @JdbcTest

Наконец, если мы используем Spring Boot, есть аннотация, которую мы можем использовать для начальной загрузки теста с базой данных H2 и JdbcTemplate bean: @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 .