在C#中测试控制台进出控制台应用程序

时间:2015-07-29 17:31:35

标签: c# unit-testing

我在测试中遇到了问题" Console in"和"控制台输出"在C#控制台应用程序中。

如果我使用Console.WriteLine和Console.ReadLine,我可以使用NUnit框架来测试应用程序,但如果我使用帮助程序类进入并输出到控制台,我就无法使其工作。

帮助程序类是https://open.kattis.com/download/Kattio.cs并使用BufferedStream写入控制台,但我无法通过测试来阅读它...

它使用了一个StreamReader用于"控制台在"但是我得到了一个" NoMoreTokenException"我猜它没有得到任何意见......

我想使用帮助程序类,但我无法使用它进行测试...

例: 测试用例:

    [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);

例如:无法运作的代码:

        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 ();

任何人如何解决这个问题?

1 个答案:

答案 0 :(得分:5)

正如@juharr在评论中提到的,调用Console.OpenStandardInput将重置输入流。因此,您需要使辅助类可测试控制台流。 (仅限您可以更改实施)。

首先,可以更新Tokenizer类以将控制台Reader用作默认的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:无法使用的代码摘要。