Модульное тестирование DAL - пожалуйста, критикуйте - PullRequest
1 голос
/ 27 октября 2009

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

У меня в основном есть класс FooDataAccess с несколькими очень простыми функциями, скажем, 3 из них так:

int InsertFoo(string fooName)
void UpdateFoo(int fooID, string fooName)
void InsertFoosDepedency(int fooID, string someValue)

Я сделал следующее: поместил 4 сценария SQL в мой проект модульного тестирования, последний из которых является встроенным ресурсом.

1) Создать (модульный тест) сценарий базы данных, 2) Создать сценарий объектов, 3) Вставить значения таблицы поиска и 4) Удалить все, кроме значений таблицы поиска

Идея в том, что любой, кто первым использует проект, должен вручную запускать сценарии 1-3 вручную в качестве одноразовой установки. Затем выполните скрипт № 4 при запуске каждого модульного теста ... (в небольших приложениях вы можете даже запустить их все на уровне тестирования)

Хорошо, пока все хорошо ...

Итак, у меня настроена база данных модульных тестов, как с чистого листа. Тестирование первой функции InsertFoo () очевидно очень просто. Я вызываю функцию, затем просто Assert (ExecuteSQL («выберите количество (*) из foo»)> 1), Assert (ExecuteSQL («выберите fooName из t_foo») = ожидается)) и т. Д.

Я немного застрял там, где требуются зависимости, например, 3-я функция в моем примере или даже обновление.

Имеет ли смысл временно отбросить все ограничения внешнего ключа для области моего теста? В противном случае, чтобы выполнить модульное тестирование функции InsertFoosDepedency (int fooID, string someValue), мне нужно было бы сначала выполнить какой-нибудь произвольный sql (вручную вставить запись в таблицу FOO и вернуть FooID) ...

ИЛИ, я должен просто сделать последнее?

Любая обратная связь с благодарностью.

ОБНОВЛЕНИЕ: работает чисто с встроенным SQL для создания зависимостей. Я думаю, я просто ищу комментарии и критику по этому методу для модульного тестирования DAL. Еще раз спасибо

Ответы [ 2 ]

2 голосов
/ 30 октября 2009

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

void update_existingKey_updatesValue() {
   String expected = "jeff";

   clearDatabase();
   // Note I would use dbUnit.
   executeSQL("insert into foo values (1, 'fred')");

   DAL subject = new DAL(...);
   subject.update(1, expected);  

   //Note I would use dbUnit.   
   String actual = executeSQL("select name from foo where id = 1"); 
   assert(expected, actual);
}

В Java я использую инструмент под названием dbUnit , ваши имена методов предлагают C #, поэтому я укажу вам на dbUnit.Net , однако я никогда не использовал это. Это обеспечивает более приятный (во всяком случае, IMO) метод заполнения базы данных и проверки содержимого базы данных.

1 голос
/ 27 октября 2009

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

Можете ли вы использовать Макет объектов ?

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

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

Или вам просто нужно выполнить настройку для конкретного теста в методе Test (и вы можете использовать Teardown, чтобы впоследствии очистить БД).

...