@Qvabrik

Как протестировать функцию, в которой пользователь вводит данные?

Добрый день, господа разработчики!

Я делаю небольшой проект консольной игры, и стараюсь охватить юнит тестами максимальное количество функций. Для тестирования использую Google Test. У меня возникло затруднение с тестированием простой, но важной функции:

void Players::CreatePlayer() {
	std::cout << "Введите имя игрока: ";
	std::string name = ReadLine();
	//проверим, что такого игрока нет
	while (CheckName(name)) {
		std::cout << "Такой игрок уже есть. Попробуйте ещё раз!\nВведите имя игрока:";
		name = ReadLine();
	}
	AddPlayer(name);
}
//ReadLine - это вспомогательная функция для считывания строки


Вот какая логика тут реализована:
1. Есть private-функция AddPlayer, которая добавляет игрока в private-множество.
2. Функция CreatePlayer является public функцией, которая позволяет считать имя игрока, валидировать его через private-функцию CheckName и передать в AddPlayer.

Я хочу написать тестировать эту логику через юнит тест. Но как это сделать, если в CreatePlayer нужно вводить данные, а AddPlayer является private?

Я думал о двух вариантах:
1. Вытащить AddPlayer в public, но делать этого не хочется, т.к. в моей задумке пользователь напрямую не взаимодействует с этой функцией.
2. Позволить тестам залезть в private-секцию через #define private public, как это описано здесь. Но, насколько я понял
...this suggestion is extremely bad coding practice

В итоге, какой наиболее корректный способ есть решить эту проблему? Если менять архитектуру, то как?
  • Вопрос задан
  • 136 просмотров
Решения вопроса 1
Alexandroppolus
@Alexandroppolus
кодир
При запуске теста задать stdin и stdout, наверно, как-то так.

Вообще, у тебя тут хреновая классовая декомпозиция. Класс, занимающийся "коллекцией игроков", не должен зашивать в себя какое-либо взаимодействие с пользователем. Так что да, быть методу AddPlayer публичным.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Miron11
Пишу sql 20 лет. Срок :)
Did you try this?
Оператор SendKeys
The other way is to write an c/c++ program using win32 API "startprocess", grab its handle, and send to the console window keystrokes using "SendMessage" core API method, one symbol at a time.
I wonder if this is really what you want, because it looks more like testing keyboard events of a computer than your function.
Perhaps for a test you can substitute this "readline", with something that reads lines from some file, you pass to test program at the beginning in the form of input parameter from command line or using some kind of configuration approach.
This will not really invalidate your API, but reduce complexity of arranging user input to something, I'd say, reasonable.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы