У меня есть метод DAO, который использует Spring для доступа JDBC. Он рассчитывает показатель успешности продавца при продаже предмета.
Вот код:
public BigDecimal getSellingSuccessRate(long seller_id) {
String sql = "SELECT SUM(IF(sold_price IS NOT NULL, 1, 0))/SUM(1)
FROM transaction WHERE seller_id = ?";
Object[] args = {seller_id};
return getJdbcTemplate().queryForObject(sql, args, BigDecimal.class);
}
Как мне пройти тестирование этого метода или любого метода DAO с помощью JUnit? Каковы некоторые рекомендации по проверке логики доступа к данным? Я думаю о том, чтобы протестировать его на встраиваемой базе данных, загруженной некоторыми данными, но разве мы не должны проводить интеграционные тесты, аналогичные производственной среде, с точки зрения СУБД и схемы?
Ответы:
Проблема с использованием «реальной» базы данных для модульного тестирования заключается в установке, отключении и изоляции тестов. Вам не нужно раскручивать совершенно новую базу данных MySQL и создавать таблицы и данные только для одного модульного теста. Проблемы с этим связаны с внешним характером базы данных, и ваша тестовая база данных не работает, ваши модульные тесты не пройдены. Есть также проблемы с проверкой наличия уникальной базы данных для тестирования. Их можно преодолеть, но есть более простой ответ.
Пересмешивать базу данных - один из вариантов однако он не проверяет фактические запросы, которые выполняются. Его можно использовать как гораздо более простое решение, если вы хотите убедиться, что данные из DAO проходят через систему должным образом. Но для тестирования самого DAO вам нужно что-то стоящее за DAO, у которого есть данные и запросы выполняются правильно.
Первое, что нужно сделать, это использовать базу данных в памяти. HyperSQL является отличным выбором для этого, потому что он способен эмулировать диалект другой базы данных, так что незначительные различия между базами данных остаются неизменными (типы данных, функции и тому подобное). hsqldb также имеет несколько полезных функций для модульного тестирования.
Это загружает состояние базы данных (таблицы, исходные данные) из
testData
файла.shutdown=true
автоматически отключит базу данных при закрытии последнего соединения.Используя внедрение зависимостей , предложите юнит-тестам выбрать другую базу данных, чем та, которую используют производственные (или тестовые, или локальные) сборки.
Затем ваш DAO использует внедренную базу данных, для которой вы можете запускать тесты для базы данных.
Модульные тесты будут выглядеть примерно так (куча скучных вещей для краткости не включена):
И, таким образом, у вас есть модульный тест, который вызывает DAO и использует данные, которые были настроены в оперативной базе данных, которая существует на время теста. Вам не нужно беспокоиться о внешних ресурсах или состоянии базы данных перед запуском или восстановлением известного состояния (ну, «известное состояние» - это «не существует», к которому тривиально вернуться).
DBUnit может сделать большую часть того, что я описал, более простым процессом настройки базы данных, создания таблиц и загрузки данных. Если по какой-то причине вам понадобится использовать реальную базу данных, это лучший инструмент для использования.
Приведенный выше код является частью проекта maven, который я написал для доказательства концепции TestingWithHsqldb на github.
источник
sql.syntax_mys=true
которые изменяют способ работы hsqldb: «Когда установлено это значение, это свойство включает поддержку типов TEXT и AUTO_INCREMENT, а также обеспечивает совместимость с некоторыми другими аспектами этого диалекта». в то времяsql.syntax_ora=true
как «Это свойство, если оно установлено в true, включает поддержку нестандартных типов. Оно также включает синтаксис DUAL, ROWNUM, NEXTVAL и CURRVAL, а также обеспечивает совместимость с некоторыми другими аспектами этого диалекта».Во-первых, вы никогда не должны проводить тестирование в производственной среде. У вас должна быть тестовая среда, которая отражает вашу производственную среду и проводить там интеграционные тесты.
Если вы это сделаете, то вы можете сделать несколько вещей.
источник
В нашем проекте каждый разработчик работает с пустой базой данных, ее структура совпадает с производственной базой данных.
В каждом модульном тесте TestInitialize мы создаем соединение и транзакцию с базой данных, а также некоторые объекты по умолчанию, которые нам нужны для каждого теста. И все откатывается после окончания каждого метода или класса.
Таким образом, можно протестировать слой sql. Фактически, каждый запрос или вызов базы данных должен быть проверен таким образом.
Недостатком является то, что он медленный, поэтому мы помещаем его в отдельный проект из наших обычных модульных тестов. Можно ускорить это, используя базу данных в памяти, но идея остается той же.
источник