Answer the question
In order to leave comments, you need to log in
How to write a unit test for keyboard input?
using System;
using System.Threading;
using System.Collections.Generic;
public class EventLoop
{
private ManualResetEventSlim _messageEvent = new ManualResetEventSlim(false);
private Queue<Int32> _messageQueue = new Queue<Int32>();
public int sum = 0;
public void Threadmain()
{
var thrd = new Thread(PumpMessage);
thrd.Start();
WriteLine("Enter first number to summarize, enter q or Q to stop");
while (true)
{
var message = WaitMessage();
sum += message;
WriteLine("Current sum:" + Convert.ToString(sum));
if (Convert.ToString(message) == "q" || Convert.ToString(message) == "Q")
{
WriteLine("The final sum is" + Convert.ToString(sum));
break;
}
}
}
private int WaitMessage()
{
_messageEvent.Wait();
var message = _messageQueue.Dequeue();
_messageEvent.Reset();
return Convert.ToInt32(message);
}
private void PumpMessage()
{
while (true)
{
var num = ReadLine();
if (num == "q" || num == "Q")
{
WriteLine("The final sum is" + Convert.ToString(sum));
break;
}
_messageQueue.Enqueue(Convert.ToInt32(num));
_messageEvent.Set();
}
}
public virtual string ReadLine()
{
return Console.ReadLine();
}
public virtual void WriteLine(string strline)
{
Console.WriteLine(strline);
}
}
public class Program
{
static void Main(string[] args)
{
EventLoop obj = new EventLoop();
obj.Threadmain();
}
}
Answer the question
In order to leave comments, you need to log in
Если вы действительно хотите тестировать ввод с клавиатуры, это значит что вам нужно замокать статический метод.
У Fody есть add-in Fody.Ionad, который позволяет делать как раз именно это.
Но, конечно, будет правильнее воспользоваться советом предыдущих ответчиков, и переделать код так, чтобы он был более тестируем.
Пример, когда платят за строку кода :)
Код абсолютно НЕ тестопригодный, вы постарались.
На ввод с клавиатуры юнит-тест не нужен. Нужен юнит-тест на метод, который производит с этим вводом какие-либо действия. Основная логика у вас происходит именно в Threadmain() - методе, который ничего не принимает и ничего не возвращает, кроме возможных исключений.
1. Зачем ввод с клавиатуры в отдельном потоке, да ещё и с очередью, если ReadLine() блокирующий метод.
2. Convert.ToInt32() выдаст исключение, если аргументом будет строка, не содержащая цифры.
3. num == "q" || num == "Q"
- есть методы .ToLower(), ToUpper(). Название переменной num абсолютно нелогично, если оно не числовое.
4. Ещё тестом надо покрыть PumpMessage(), чтобы проверить, выходит ли программа из цикла
UPD: Вот рефактор, который делает более-менее то же самое, и его можно тестировать:
using System;
using System.Linq;
using System.Collections.Generic;
class Program {
static List<int> _numbers = new List<int>();
static void Main() {
while(UserInput(Console.ReadLine()));
Console.WriteLine($"Sum is: {CalcSum(_numbers)}");
}
static bool UserInput(string input)
{
if(string.IsNullOrEmpty(input)) return false;
if(!int.TryParse(input, out int number)) return false;
_numbers.Add(number);
return true;
}
static int CalcSum(IEnumerable<int> numbers)
{
return numbers.Sum();
}
}
Unit тесты, судя из названия, предназначены для тестирования функциональности модулей и отдельных методов, ни одним unittest фреймворком вы не провернете это, а у вас получается интеграционный тест. Пишем еще одно приложение, которое будет перехватывать ввод/вывод с консоли и тестировать ваше приложение. Вот для примера
https://www.codeproject.com/Questions/720259/How-t...
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question