Написание единиц измерения для метода, который запрашивает базу данных
Я изучаю TDD, и в настоящее время у меня есть метод, который работает, но я подумал, что мне придется перестраивать его с помощью TDD.
Метод по существу принимает 6 параметров, запрашивает базу данных, выполняет некоторую логику и возвращает List<T>
Мои начальные тесты, включая проверку значений пустых/нулевых строк и значений метода int, но теперь я не уверен, что делать. Если бы я не использовал TDD, я бы просто создал код, чтобы найти строку подключения к БД и открыть соединение с БД, запросить базу данных, прочитать значения и т.д.
Очевидно, мы не можем это сделать в Unit Testing, поэтому я после некоторого совета о том, как действовать.
Ответы
Ответ 1
Помните, что TDD имеет такой же дизайн, как и для тестирования. Этот метод слишком много продолжается; это нарушает принцип "Разделение проблем".
Вы уже определили несколько областей, которые необходимо будет протестировать:
Метод по существу принимает 6 параметров, запрашивает базу данных, выполняет некоторую логику и возвращает List<T>
У вас есть несколько дискретных шагов, и, вероятно, есть еще несколько скрытых в коде. Ломать их - это название игры, когда дело доходит до TDD.
Во-первых, может быть хорошей идеей отбросить часть, которая выполняет логику.
Является ли ваш метод построением запроса динамически? Разбейте эту часть и проверьте ее, чтобы убедиться, что запрос написан правильно.
Вы можете поместить выполнение запроса в автономный репозиторий или что-то подобное, и выполнить тесты интеграции с этим. Таким образом, у вас есть простой тест, попавший в базу данных вместо текущего сложного метода.
Если вы попытаетесь проверить это как есть, вы, скорее всего, закончите тест монстра, который требует много настроек и дублирует всю вашу бизнес-логику, и когда он сломается, будет неясно, что пошло не так,
Ответ 2
В общем, нет ничего плохого в использовании TDD для проверки кода базы данных. Однако вы можете попробовать абстрагироваться от кода базы данных, а затем издеваться над ней.
Ответ 3
Метод по существу принимает 6 параметров, запрашивает базу данных, делает некоторая логика и возвращает список
Кажется, что это слишком много, чтобы быть единым проверяемым кодом!
Единичный тестируемый код должен делать очень конкретные вещи и делать это в небольших модулях. Итак, в вашем случае вам нужно реорганизовать и разбить свой метод на следующие (по крайней мере):
- запрос базы данных: завершен внутри DataProvider с помощью интерфейса поддержки. И ваш unit test издевается над этим интерфейсом.
- делает некоторую логику: это лучший кандидат для unit test. Это должен быть модуль, который просто использует интерфейс поставщика данных и выполняет логику и возвращает измененный список, который вы будете проверять в unit test.
Кроме того, помните, что unit test должен охватывать не менее трех сценариев для каждого тестируемого модуля:
- положительный тест
- отрицательный тест
- тест, бросающий значащее исключение для недопустимых значений.
Надеюсь, что это будет полезно.
Ответ 4
Другой вариант - начать транзакцию перед тестом и выполнить откат потом. Таким образом, тесты независимы, поэтому, согласно некоторым определениям, можно считать модульными тестами.
Вопреки тому, что упоминалось в других ответах, вы должны реорганизовать код, чтобы получить лучший дизайн после прохождения теста. Затем вы можете проверить, что ваш рефакторинг не нарушил ничего, просто повторив тест.
Ответ 5
Возможно, вы захотите попробовать DbUnit для запуска модульных тестов на вашем уровне доступа к данным. Он помещает вашу базу данных в известное состояние между тестовыми запусками, предотвращающими повреждение тестовой базы данных.
Ответ 6
Вы можете:
- Используйте init/class для сборки пустой БД или копии небольшой БД с известным набором данных.
- В методе тестирования введите тестовые данные (если БД пуста), затем выполните запрос, а затем сравните результат с ожидаемым результатом.
- В очистке теста/класса удалите БД.
Это тестирование вашего устройства, но некоторые считают "интеграционным тестом".
- Термин "unit test" имеет некоторые разногласия из-за двусмысленности термина "единица".
Вы также можете использовать внутреннюю память или встроенную базу данных, чтобы упростить тестовую среду.