2015-07-29 2 views
4

У меня возникла проблема с тестированием «Консоль в» и «Консоль» в консольном приложении C#.Тестирование консольного консольного приложения в C#

Если я использую Console.WriteLine и Console.ReadLine, я могу использовать инфраструктуру NUnit для тестирования приложения, но если я использую вспомогательный класс для ввода и вывода на консоль, я не могу заставить его работать.

Хелпер класс https://open.kattis.com/download/Kattio.cs и использует BufferedStream написать в консоли, но я не могу получить мой тест, чтобы прочитать это ...

Он использует StreamReader для «консоли в», но я получаю «NoMoreTokenException ", который я предполагаю, что это не получаю вход ...

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

Ex: TestCase:

[Test] 
    public void test_hello_world() 
    { 
     using (var sw = new StringWriter()) {    
      Console.SetOut (sw); 
      using (var sr = new StringReader ("Start")) { 
       Console.SetIn (sr); 
       MainClass.Main(new string[]{}); 
       string expected = "Hello World!\n"; 
       Assert.AreEqual (sw.ToString(), expected); 
      } 
     } 
    } 

Ex: Код, который работает:

string line = ""; 
    if (Console.ReadLine().Equals("Start")) 
     line = "Hello World!"; 
    else 
     line = "No such luck!"; 
    Console.WriteLine (line); 

Ex: Код, который не работает:

 string line = ""; 
     Scanner sc = new Scanner(); 
     if (sc.Next().Equals ("Start")) 
      line = "Hello World!"; 
     else 
      line = "No such luck!"; 
     BufferedStdoutWriter outWritter = new BufferedStdoutWriter(); 
     outWritter.WriteLine (line); 
     outWritter.Flush(); 

Любое имея представление о том, как решить эту проблему?

+0

Если вы посмотрите на [документация] (https://msdn.microsoft.com/en-us/library/tx55zca2 (v = vs.110) .aspx) для 'Console.OpenStandardInput', он говорит: этот метод может использовать для повторного ввода стандартного потока ввода после того, как он был изменен с помощью метода SetIn. Я полагаю, что это означает, что он отменяет «Console.SetIn», и поэтому он фактически читает из консоли вместо вашего «StringReader». – juharr

+0

Возможно, вы сможете это сделать, запустив свою программу в отдельном процессе и передав входной сигнал и получив от него вывод. – juharr

+0

Связанный (дубликат?): Http://stackoverflow.com/q/2139274/126014 –

ответ

5

Как @juharr упоминает в комментарии, что вызов Console.OpenStandardInput сбрасывает входной поток. Таким образом, вам нужно сделать класс-помощник для консольных потоков. (Только если вам разрешено изменить реализацию).

Первый класс Tokenizer может быть обновлен, чтобы использовать Ридер консоль как по умолчанию TextReader:

public class Tokenizer 
{ 
    string[] tokens = new string[0]; 
    private int pos; 

    // StreamReader reader; Changed to TextReader 
    TextReader reader; 

    public Tokenizer(Stream inStream) 
    { 
     var bs = new BufferedStream(inStream); 
     reader = new StreamReader(bs); 
    } 

    public Tokenizer() 
    { 
     // Add a default initializer as Console Input stream reader. 
     reader = Console.In; 
    } 

    // ...... Rest of the code goe here............... 
    // ..................... 
} 

изменения также выход писателя буфера к следующему:

Обновлено - Конструктор принимает другие потоки.

public class BufferedStdoutWriter 
{ 
    public TextWriter Writer; 

    public BufferedStdoutWriter() 
    { 
     // Use default writer as console output writer 
     this.Writer = Console.Out; 
    } 

    public BufferedStdoutWriter(Stream stream) 
    { 
     Writer = new StreamWriter(new BufferedStream(stream)); 
    } 
    public void Flush() 
    { 
     Writer.Flush(); 
    } 

    public void Write<T>(T value) 
    { 
     Writer.Write(value); 
    } 

    public void WriteLine<T>(T value) 
    { 
     Writer.WriteLine(value); 
    } 
} 

могут аналогичным образом выполнение нескольких функций, если это необходимо.

Теперь ваш тест успешно пройдет для EX: Код, который не работает фрагмент.

Смежные вопросы