Тестирование DAO и сервисного уровня с базой данных в памяти и mocking - PullRequest
0 голосов
/ 30 октября 2018

Во время обучения тестированию на Java я столкнулся с вещью, которую на самом деле не понял. Итак, в основном у меня есть модульные тесты для DAO, где я тестирую операции CRUD с помощью базы данных HSQL в памяти.
Что ж, следующим шагом является проверка уровня сервиса. В Интернете говорят, что имитируют DAO, а затем тестируют Service.

Я вижу только один способ использовать mocks: если в Service есть несколько методов, и эти методы не существуют в DAO. Тогда нам не нужно тестировать работу CRUD (сам DAO), поэтому мы имитируем DAO и тестируем только Service.

  1. Но что, если у меня в Сервисе те же методы, что и в DAO?
  2. А что, если я просто использую базу данных в памяти для тестирования Service, как я это делал с DAO?

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

Если это имеет смысл - я использую Spring.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Исходя из опыта (написав тысячи автоматических тестов):

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

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

  3. Используйте вашу базу данных разработки (обычно это общая удаленная БД, использующая тот же механизм БД, что и в производственной среде, где приложение также может быть проверено вручную), а не БД в памяти. Таким образом, вы избегаете дорогостоящего создания схемы БД в памяти при каждом запуске теста (при условии, что dev db всегда запущен и работает со всеми таблицами, что обычно имеет место), и любых потенциальных проблем, вызванных использованием двух разных технологий БД .

Выше описан подход, который я использую в веб-приложениях Java (неважно, использую Java EE или Spring) с сотнями таблиц в реляционном БД (доступ к которому осуществляется через JPA / Hibernate). Существует только один набор тестов вне контейнера интеграционных тестов, где каждый тест выполняется в одной транзакции БД, которая всегда откатывается. Некоторые тесты немного издеваются, в частности, для звонков на удаленные веб-сервисы, но это все.

0 голосов
/ 30 октября 2018

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

Преимущество баз данных в памяти:

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

Недостатки баз данных в памяти:

  • Отсутствует полная изоляция для ваших юнит-тестов
  • Требуется инициализация контейнера DI для юнит-тестов.
  • Может обеспечивать ложное чувство безопасности в зависимости от того, насколько поставщик базы данных в памяти отличается от вашей производственной базы данных,

Преимущество издевается:

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

Недостатки издевательств:

  • Тестовый код может стать сложным и хрупким в зависимости от того, насколько согласованы методы обслуживания и как они связаны со слоем DAO. то есть, если вам нужно установить вызов 20 фиктивных методов и три фиктивных объекта, это быстро становится утомительным (однако это должно быть признаком того, что ваша служба нуждается в рефакторинге).

Чтобы ответить на первый вопрос, который вы задали, о том, что происходит, когда в обоих случаях используется один и тот же метод - простой ответ. Это не тот же метод. Они делают две разные вещи. Один общается с базой данных, другой применяет бизнес-логику. Если у вас есть проход, вы все равно, вероятно, должны провести тест на нем и на уровне сервисов, чтобы убедиться, что он вызывает правильную вещь в вашем DAO.

Независимо от того, куда вы идете, не забудьте также провести интеграционный тест вашего кода!

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