Как я могу использовать NUnit для тестирования метода с параметрами out или ref? - PullRequest
7 голосов
/ 15 августа 2010

Если у меня есть функция, которая принимает параметр out и принимает консоль формы ввода -

public void Test(out int a)
{
     a = Convert.ToInt16(Console.ReadLine());  
}

Как я могу принять ввод с помощью Console.Readline () во время теста NUnit?Как я могу использовать NUnit для тестирования этого метода?

Я пытался использовать этот код для моего теста NUnit -

[TestCase]
public void test()
{
     int a = 0;   
     ClassAdd ad = new ClassAdd();
     ad.addition(out a);

     //a should be equal to the value I input through console.Readline()
     Assert.AreEqual(<some value I input>, a, "test");    
}

, как я могу протестировать метод, который принимает параметр out и также принимаетпользовательский ввод из консоли?

Ответы [ 2 ]

3 голосов
/ 15 августа 2010

Вы можете использовать SetIn метод System.Console для установки источника входного сигнала:

StringReader reader = new StringReader("some value I input" + Enivronment.NewLine);
Console.SetIn(reader);

int a = 0;   
ClassAdd ad = new ClassAdd();
ad.addition(out a);

Assert.AreEqual(<some value I input>, a, "test");

РЕДАКТИРОВАТЬ: Чтобы проверить несколько значений, просто разделите каждый вход новой строкой:

string[] lines = new[] { "line1", "line2" };
StringReader input = new StringReader(String.Join(Environment.NewLine, lines));
Console.SetIn(input);

string input1 = Console.ReadLine();    //will return 'line1'
string input2 = Console.ReadLine();    //will return 'line2'
2 голосов
/ 15 августа 2010

Здесь объединены 2 несколько разных вопроса.

  1. Вы хотите проверить метод, который возвращает значение в параметре out. Это на самом деле довольно тривиально и вряд ли отличается от метода, который возвращает свое значение как нормальную функцию.
  2. Вы хотите проверить метод, который читает ввод с консоли. Это немного сложнее, и немного затрагивает дизайн объекта, который вы пытаетесь протестировать. Проблема в том, что «Консоль» является глобальным объектом, и это сразу же усложняет тестирование.

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

В ответ на # 2 я предлагаю вам взглянуть на некоторые статьи и видео Misko Hevery по написанию тестируемого кода.

http://misko.hevery.com/2008/08/21/where-have-all-the-singletons-gone/

Для краткого описания вашей проблемы:

  • MethodToTest В настоящее время требуется ввод с консоли.
  • Класс, содержащий MethodToTest, должен принимать «входной поток» в своем конструкторе. (Этот метод называется внедрением зависимостей.)
  • В производственном коде ваш класс будет создан с обычной консолью в качестве входного потока.
  • В тестовом коде класс будет создан с входным потоком Mock , который будет передавать значения, контролируемые тестом.
  • Таким образом, ваш тест может быть автоматизирован и хорошо контролироваться с точки зрения входных данных; и, следовательно, ожидаемые результаты.

Пример кода "Голые кости"

[TestCase] 
public void test() 
{ 
  <use appropriate type here> MockInputStream = new ...;
  ClassToTest testClass = new ClassToTest(MockInputStream);

  int Actual = 0;
  MockInputStream.PutNextInput("4");
  ClassToTest.MethodToTest(out Actual);

  Assert.AreEqual(4, Actual, "MockInputStream placed 4 as the next value to read");
} 
...