Написание модульных тестов для метода, который запрашивает базу данных - PullRequest
12 голосов
/ 25 января 2012

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

Метод, по сути, принимает 6 параметров, запрашивает базу данных, выполняет некоторую логику и возвращает List<T>

Мои начальные тесты, включая проверку на наличие пустой / нулевой заданной строки и значений параметров метода int, но теперь я не уверен, что делать. Если бы я не использовал TDD, я просто создал бы код, чтобы найти строку соединения с БД и открыть соединение с БД, запросить базу данных, прочитать значения и т. Д.

Очевидно, что мы не можем сделать это в модульном тестировании, поэтому я получил несколько советов о том, как действовать.

Ответы [ 6 ]

9 голосов
/ 25 января 2012

Помните, что TDD так же важен для хорошего дизайна, как и для тестирования.У этого метода слишком много всего происходит;это нарушает принцип разделения проблем.

Вы уже определили несколько областей, которые необходимо проверить:

Метод, по сути, принимает 6 параметров, запрашивает базу данных, выполняет некоторую логику и возвращает List<T>

У вас есть несколько отдельных шагов, и, вероятно, есть еще несколько скрывающихся в коде.Разбиение на части - это название игры, когда дело доходит до TDD.

Для начала, было бы неплохо выделить часть, которая выполняет логику.

Ваш метод динамически формирует запрос?Разбейте этот фрагмент и проверьте его, чтобы убедиться, что запрос написан правильно.

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

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

6 голосов
/ 25 января 2012

В общем, нет ничего «неправильного» в использовании TDD для тестирования кода базы данных. Однако вы можете попытаться абстрагировать код базы данных, а затем максимизировать его.

4 голосов
/ 25 января 2012

Метод, по сути, принимает 6 параметров, запрашивает базу данных, делает некоторая логика и возвращает список

Кажется, это слишком много, чтобы быть кодом, проверяемым модулем !!

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

  • запрос базы данных: обернут внутри DataProvider с интерфейсом поддержки. И ваш юнит-тест будет издеваться над этим интерфейсом.
  • делает некоторую логику: это лучший кандидат для юнит-теста. Это должен быть модуль, который просто принимает интерфейс поставщика данных, выполняет логику и возвращает измененный список, который вы проверите в своем модульном тесте.

Кроме того, помните, что модульное тестирование должно охватывать как минимум три сценария для каждого тестируемого модуля:

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

Надеюсь, это полезно.

2 голосов
/ 17 мая 2015

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

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

1 голос
/ 25 января 2012

Вы можете:

  1. Используйте класс / test init для создания пустой БД или копии небольшой БД с известным набором данных.
  2. В методе теста введите данные теста (если БД пуста), затем выполните запрос, затем сравните результат с ожидаемым результатом.
  3. В тесте / классе очистки удалите БД.

Это тестирует ваш юнит, но некоторые считают его "интеграционным тестом". - Термин «модульный тест» имеет некоторые разногласия из-за неоднозначности термина «блок».

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

1 голос
/ 25 января 2012

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

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