Как выполнить модульное тестирование сложных объектов? - PullRequest
3 голосов
/ 12 октября 2019

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

У вас есть класс Player, в котором есть локальная переменная класса World (созданного создателем) и World объект имеет открытое соединение с базой данных.

Таким образом, метод player.breakBlock() вызовет world.breakBlockAt(x,y,z), а метод world.breakBlockAt(int x, int y, int z) выполнит изменения в базе данных и выдаст результат.

В случаяхнапример, когда у вас есть сложные «объектные зависимости», как лучше всего проводить тестирование?

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

Ответы [ 4 ]

3 голосов
/ 13 октября 2019

Чтобы протестировать свой класс Player без базы данных, вы можете использовать фреймворк, такой как EasyMock или Mockito , чтобы создать макет вашего World объекта, предварительно записавметоды, которые вы ожидаете, что ваш класс Player вызовет, а затем подтвердите, что метод действительно был вызван.

Вы также можете позволить своим фиктивным объектам перехватить вызов метода и заменить его пользовательской логикой. Например, вы можете делегировать вызов breakBlockAt методу, который изменяет HashMap вместо фактической базы данных. И возвращаемое значение может затем вести себя по-разному в зависимости от того, что предыдущие вызовы уже сделали с HashMap.

Конечно, у вас все равно должен быть отдельный тестовый пример для вашего класса World, чтобы фактически протестироватьлогика, которая работает с базой данных (но без добавления сложности класса Player сверху). Это в основном интеграционный тест, в котором вы убедитесь, что операторы JDBC или объекты JPA приводят к правильному SQL, который работает при использовании с выбранным вами диалектом базы данных. Библиотека типа Testcontainers может использоваться для настройки пустой базы данных в контейнере Docker изнутри вашего модульного теста. Единственное требование заключается в том, что в вашей тестовой среде Docker запущен и готов к выполнению.

2 голосов
/ 13 октября 2019

Зависит от того, какой тип тестирования вы хотите выполнить:

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

Обратите внимание, что для насмешек обычно используют библиотеку насмешек (например, Mockito), чтобы облегчить насмешки.

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

Более подробная информация о типах тестов

2 голосов
/ 13 октября 2019

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

Это означает, что в тесте World я буду издеваться над соединением с базой данных и писать тесты в world.breakBlockAt(x,y,z), где я буду насмехаться над БД для выполнения различных случаев.
Идея здесь не в том, чтобыпроверьте БД, но:
- что ваш код передает правильные данные в базу данных db
- что ваш код обрабатывает различные результаты, как и ожидалось.
- что ваш код правильно обрабатывает все виды ответов от db (например, правильно обрабатывает исключения)

То же самое относится к Player - на этом вы должны смоделировать мир и проверить, что ваш код в проигрывателе передает правильные значения в World, и обрабатывает нормально ответ от него

2 голосов
/ 12 октября 2019

Вы можете смоделировать, например, объект World (с такими структурами, как Mockito ) в Player, заменив breakBlockAt заглушкой, а затем убедитесь, что breakBlockAt вызвал.

Это, конечно, требует, чтобы вы могли "впрыснуть" такого фальшивого World в класс Player.

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