Код взаимодействия с базой данных - PullRequest
2 голосов
/ 28 июля 2010

Я пишу небольшое приложение, которое работает с базой данных, и я не могу понять, как проверить это взаимодействие.Мое приложение опирается на 5 хранимых процедур, которые я решил инкапсулировать в класс.Этот класс предлагает 5 открытых методов, которые выполняют процедуры и, при необходимости, преобразуют результаты в коллекции объектов.

Я действительно не могу понять, как тестировать мой код простым способом, и я думаю, что, вероятно,Я сделал несколько ошибок.

Что вы думаете о моем дизайне?Есть ли лучший способ обработать эти случаи?

Большое спасибо за вашу помощь

РЕДАКТИРОВАТЬ: Среди моих хранимых процедур есть только запросы "вставка" и "выбор".

Ответы [ 4 ]

2 голосов
/ 28 июля 2010

В общем, я бы рекомендовал не проверять вещи на работающей базе данных по нескольким причинам:

  1. Выполнение SQL может сделать ваши тесты длительными
  2. Данные могут измениться у вас под носом, что приведет к сбою тестов даже без видимых изменений кода. Вы хотите, чтобы ваши тесты были изолированными и детерминированными, поэтому они проходят или не проходят только при изменении кода.
  3. Если у вас есть код, который обновляет базу данных, вам нужно откатить свои изменения, иначе следующий запуск теста может привести к ложному положительному или ложному отрицательному значению.

Итак, для тестирования вы хотите подделать вашу базу данных. Начните с чего-то вроде этого:

public interface IDataRepository {
    Customer GetCustomerByName(string name);
    void SaveCustomer(Customer c);
    SecurityToken Login(string username, string password);
}

class DatabaseRepository : IDataRepository { ... } // invokes your stored procedures

Если вашим классам нужно что-то из базы данных, передайте IDataRepository в конструктор вашего объекта.

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

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


Теперь, если вам нужно для проверки ваших хранимых процедур, вы должны написать тесты для вашего DatabaseRepository класса напрямую.

Вам необходимо после каждой проверки переустанавливать свою базу данных в исходное состояние, чтобы вы либо запускали все в транзакции и откате, либо создавали новую базу данных с чистыми данными при каждом запуске теста. Я предпочитаю последний подход - слишком просто оставить транзакцию открытой или забыть откатить ее и, следовательно, уничтожить все ваши тестовые данные.

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

Я бы подумал, что это скорее системный или интеграционный тест, а не модульный тест.

0 голосов
/ 28 июля 2010

Сначала вы должны получить базу данных для разработчиков .Вы можете использовать базу данных в памяти, но я нахожу жизнь намного лучше, если настоящий экземпляр базы данных живет где-то в среде разработчика.Чтобы было ясно - ваша база данных разработчиков, а не общий экземпляр.

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

Ваш код содержит три элемента, которые необходимо проверить.Первый - это сортировка объектов;вторая - попадание в базу данных, и, наконец, у вас есть исключение.Возможно, стоит протестировать каждый элемент самостоятельно.Если это так, разделите маршаллинг на их собственные методы, взяв DataRow или ResultSet, и сделайте их общедоступными.

Второй элемент для проверки бита, попадающего в базу данных (интеграционный тест, но чертовски полезный - ибаза данных dev должна жить лучше. Если вы используете Oracle вживую, используйте Oracle в качестве базы данных для разработчиков).Это означает, что вам нужно настроить базу данных.В настоящее время я вручную обновляю схему и автоматизирую настройку данных с помощью такого инструмента, как dbUnit .Это может очистить данные, заполнить таблицы XML и проверить таблицы по XML-файлу.

Наконец, у вас есть обработка исключений, для этого вам нужно внедрить что-то, кроме настроек соединения, а не IDbConnection или Connection, чтобы вы могли для соединения генерировать исключение, когда оно вам тоже нужно (этопредполагается, что вы делаете что-то особенное с исключениями, если вы просто регистрируете их и позволяете им всплыть, это может не стоить проверять.

0 голосов
/ 28 июля 2010

Я часто использую автоматизированное интеграционное тестирование при работе с базами данных и их логикой. Общая идея состоит в том, чтобы настроить тестовую базу данных, используя схему для вашего приложения. В тестовом скрипте вы можете заполнить тестовую базу данных. Когда у вас все настроено, используйте ваш класс с тестовой базой данных, чтобы проверить, что все работает нормально. Измените данные и протестируйте снова.

Вам нужно будет позаботиться о создании и уничтожении тестовой базы данных при каждом запуске теста. Вам не нужны данные предыдущих тестов, иначе вы не можете точно протестировать хранимые процедуры.

Поскольку в интеграционном тестировании больше игроков, чем в юнит-тестировании, вам придется выполнить больше работы по настройке и очистке.

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

0 голосов
/ 28 июля 2010

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

Теперь, если вы пытаетесь проверить качество данных, я не думаю, что это правильный способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...