Что делает репозиторий - это переводит из вашего домена в вашу инфраструктуру DAL, такую как NHibernate или Doctrine, или ваши классы, выполняющие SQL. Это означает, что ваш репозиторий будет вызывать методы в указанной платформе для выполнения своих обязанностей: ваш репозиторий создает запросы, необходимые для извлечения данных. Если вы не используете ORM-каркас (я надеюсь, что вы ...), репозиторий будет местом, где создаются необработанные SQL-операторы.
Основным из этих методов является сохранение: в большинстве случаев он просто передает объект из хранилища на единицу работы (или сеанс).
public void Save(Car car)
{
session.Save(car);
}
Но давайте рассмотрим другой пример, например, выбор автомобиля по его идентификатору. Это может выглядеть как
public function GetCarWithId(String id)
{
return Session.QueryOver<Car>()
.Where(x => x.Id == id)
.SingleOrDefault();
}
Все еще не слишком сложно, но вы можете себе представить, что при нескольких условиях (приведите мне все машины, выпущенные после 2010 года для всех марок группы Volkswagen), это становится сложно. Таким образом, в истинной моде TDD вы должны проверить это. Есть несколько способов сделать это.
Вариант 1: имитация вызовов, сделанных в рамках ORM
Конечно, вы можете смоделировать Session-объект и просто утверждать, что сделаны правильные вызовы. Хотя это тестирует хранилище, на самом деле это не тестирование , потому что вы просто проверяете, что хранилище выглядит так, как вы этого хотите. Тест в основном говорит «код должен выглядеть так». Тем не менее, это правильный подход, но кажется, что этот вид теста имеет очень мало значения.
Вариант 2: (Пере) построить базу данных из тестов
Некоторые DAL-структуры дают вам возможность построить полную структуру базы данных на основе файлов сопоставления, которые вы создаете для сопоставления домена с таблицами. Для этих платформ способом тестирования репозиториев часто является создание базы данных с базой данных в памяти на первом этапе теста и добавление объектов с использованием DAL-инфраструктуры в базу данных в памяти. После этого вы можете использовать хранилище в базе данных в памяти, чтобы проверить, работают ли эти методы. Эти тесты медленнее, но очень эффективны и управляют вашими тестами. Это требует некоторого сотрудничества с вашей DAL-структурой.
Вариант 3: тестирование на реальной базе данных
Другой подход заключается в тестировании реальной базы данных и изоляции тестового модуля. Вы можете сделать это несколькими способами: окружить свои тесты транзакцией, очистить вручную (не рекомендуется, так как это очень сложно поддерживать), полностью перестроить базу данных после каждого шага ... В зависимости от приложения, которое вы создаете, это может или может потребоваться не быть осуществимым В моих приложениях я могу полностью создать локальную базу данных разработки из системы контроля версий, и мои тесты юнитов в репозиториях используют транзакции для полной изоляции тестов друг от друга (открытая транзакция, вставка данных, тестовый репозиторий, транзакция отката). Каждая сборка сначала настраивает локальную базу данных разработки, а затем проводит изолированные тесты транзакций для репозиториев в этой локальной базе данных разработки. Это'
Не проверяйте DAL
Если вы используете платформу DAL, такую как NHibernate, избегайте необходимости тестировать эту платформу. Вы можете проверить свои файлы сопоставления, сохранив, извлекая и затем сравнивая объект домена, чтобы убедиться, что все в порядке (обязательно отключите любой вид кэширования), но это не так требуется, как многие другие тесты, которые вы должны писать. Я склонен делать это в основном для коллекций родителей с условиями для детей.
При тестировании возврата ваших репозиториев вы можете просто проверить, соответствует ли какое-либо идентифицирующее свойство вашего объекта домена. Это может быть идентификатор, но в тестах часто выгоднее проверять читабельное свойство. В разделе «Принеси мне все машины, произведенные после 2010 года…» можно просто проверить, что пять машин возвращены, а номерные знаки - «вставить список здесь». Дополнительным преимуществом является то, что это заставляет вас думать о сортировке, а ваш тест автоматически форсирует сортировку. Вы будете удивлены тем, сколько приложений либо сортируют несколько раз (возвращают отсортированные из базы данных, сортируют перед созданием объекта представления, а затем сортируют объект представления, на всякий случай , все по одному и тому же свойству ), либо неявно принимают сортировку хранилища и случайно удаляют что-то по пути, ломая пользовательский интерфейс.
«Юнит тест» - это просто название
На мой взгляд, юнит-тесты в основном не должны попадать в базу данных. Вы создаете приложение таким образом, чтобы каждый фрагмент кода, которому нужны данные из источника, делал это с хранилищем, а этот хранилище внедрялся как зависимость. Это позволяет легко высмеивать и все, что вы хотите, TDD. Но, в конце концов, вы хотите убедиться, что ваши репозитории выполняют свои обязанности, и если самый простой способ сделать это - попасть в базу данных, ну, пусть будет так. Я давно отказался от идеи, что «модульные тесты не должны касаться базы данных», и понял, что для этого есть очень реальные причины. Но только если вы можете сделать это автоматически и неоднократно. И погода, которую мы называем таким тестом, «модульный тест» или «интеграционный тест», является спорным.