【问题标题】:Testing console in and out console application in C#在 C# 中测试控制台输入和输出控制台应用程序
【发布时间】:2015-07-29 17:31:35
【问题描述】:

我在 C# 控制台应用程序中测试“控制台输入”和“控制台输出”时遇到问题。

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

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

它为“Console in”使用 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);
            }
        }
    }

例如:有效的代码:

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

有人知道如何解决这个问题吗?

【问题讨论】:

  • 如果您查看documentation 中的Console.OpenStandardInput,它会说此方法可用于在标准输入流被 SetIn 方法更改后重新获取它。我认为这意味着它正在撤消Console.SetIn,因此它实际上是从控制台读取而不是您的StringReader
  • 您可以通过在单独的进程中启动程序并传递输入并从中获取输出来实现这一目标。
  • 相关(重复?):stackoverflow.com/q/2139274/126014

标签: c# unit-testing


【解决方案1】:

正如@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: Code that don't work sn-p.

【讨论】:

    猜你喜欢
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多