在C#中测试控制台应用程序的输入输出控制台。

4

我在C#控制台应用程序中测试“Console in”和“Console out”时遇到了问题。

如果我使用Console.WriteLine和Console.ReadLine,我可以使用NUnit框架来测试该应用程序,但是如果我使用一个帮助类来进行输入输出,我无法使其正常工作。

这个帮助类是https://open.kattis.com/download/Kattio.cs,它使用BufferedStream向控制台写入数据,但我无法让我的测试读取它...

它使用StreamReader用于“Console in”,但我得到了一个“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);
            }
        }
    }

例子:工作的代码:

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

有没有任何关于如何解决这个问题的见解?


如果您查看Console.OpenStandardInput文档,它说:“此方法可用于在SetIn方法更改标准输入流后重新获取标准输入流。” 我理解这意味着它正在撤消Console.SetIn,因此实际上是从控制台而不是您的StringReader读取。 - juharr
你可以通过在单独的进程中启动程序并传递输入并获取输出来完成这个任务。 - juharr
相关(重复?):https://dev59.com/knI95IYBdhLWcg3wzhd9 - Mark Seemann
1个回答

6

正如 @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);
    }
}

类似地,如果需要,可以实现更多的功能。 现在你的测试将成功通过“不起作用的代码”片段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接