Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中测试控制台输入和输出控制台应用程序#_C#_Unit Testing - Fatal编程技术网

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

C# 在C中测试控制台输入和输出控制台应用程序#,c#,unit-testing,C#,Unit Testing,我在C#控制台应用程序中测试“控制台输入”和“控制台输出”时遇到问题 如果我使用Console.WriteLine和Console.ReadLine,我可以使用NUnit框架来测试应用程序,但是如果我使用一个helper类来输入和输出到控制台,我就无法让它工作 helper类是并使用BufferedStream写入控制台,但我无法让测试读取它 它使用StreamReader作为“Console in”,但我得到了一个“NoMoreTokenException”,我猜它没有得到任何输入 我想使用h

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

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

helper类是并使用BufferedStream写入控制台,但我无法让测试读取它

它使用StreamReader作为“Console in”,但我得到了一个“NoMoreTokenException”,我猜它没有得到任何输入

我想使用helper类,但我无法使用它进行测试

例: 测试用例:

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

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

正如@juharr在评论中提到的,调用Console.OpenStandardInput将重置输入流。因此,您需要使helper类对于控制台流是可测试的。(仅当允许您更改实现时)

首先,可以更新标记器类,将控制台读取器用作默认文本读取器:

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...............
    // .....................
}
同时将缓冲区输出写入器更改为以下内容:

已更新-构造函数也将接受其他流

公共类BufferedStdoutWriter
{
公共文本作者;
公共缓冲stdoutwriter()
{
//将默认编写器用作控制台输出编写器
this.Writer=Console.Out;
}
公共缓冲stdoutwriter(流)
{
Writer=newstreamwriter(newbufferedstream(stream));
}
公共图书馆
{
Writer.Flush();
}
公共无效写入(T值)
{
Writer.Write(值);
}
公共无效写入线(T值)
{
Writer.WriteLine(值);
}
}
同样,如果需要,也可以实现更多功能


现在,您的测试将成功通过示例:无法工作的代码代码片段。

如果您查看控制台。OpenStandardInput,它表示此方法可用于在SetIn方法更改标准输入流后重新获取标准输入流。我认为这意味着它正在撤消
控制台.SetIn
,因此它实际上是从控制台而不是从
StringReader
读取。您可以通过在单独的进程中启动程序并传递输入并从中获取输出来实现这一点。相关(重复?):
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);
    }
}