如何使用NUnit测试带有out或ref参数的方法?

时间:2010-08-15 14:08:59

标签: c# nunit console-application

如果我有一个接受out参数并接受输入表单控制台的函数 -

public void Test(out int a)
{
     a = Convert.ToInt16(Console.ReadLine());  
}

如何在NUnit测试期间使用Console.Readline()接受输入?如何使用NUnit测试此方法?

我尝试将此代码用于我的NUnit测试用例 -

[TestCase]
public void test()
{
     int a = 0;   
     ClassAdd ad = new ClassAdd();
     ad.addition(out a);

     //a should be equal to the value I input through console.Readline()
     Assert.AreEqual(<some value I input>, a, "test");    
}

如何测试接受out参数的方法并接受来自Console的用户输入?

2 个答案:

答案 0 :(得分:3)

您可以使用SetIn的{​​{1}}方法设置输入源:

System.Console

编辑:要测试多个值,只需用新行分隔每个输入:

StringReader reader = new StringReader("some value I input" + Enivronment.NewLine);
Console.SetIn(reader);

int a = 0;   
ClassAdd ad = new ClassAdd();
ad.addition(out a);

Assert.AreEqual(<some value I input>, a, "test");

答案 1 :(得分:2)

这里有两个略有不同的问题。

  1. 您想测试一个在out参数中返回值的方法。这实际上非常简单,与将其值作为正常函数返回的方法几乎没有什么不同。
  2. 您想测试从控制台读取输入的方法。这一点相当棘手,并且稍微考虑了您要测试的对象的设计。问题是“控制台”是一个全局对象,这会立即使测试更加困难。
  3. 最值得注意的是,您要测试从控制台获取输入的方法。即这意味着用户互动。这不是你想“自动化测试”的方法吗?

    在回答#2时,我建议你看看Misko Hevery的一些关于编写可测试代码的文章和视频。

    http://misko.hevery.com/2008/08/21/where-have-all-the-singletons-gone/

    有关您问题的简要摘要:

    • MethodToTest目前需要来自控制台的输入。
    • 包含MethodToTest的类应在其构造函数中使用“输入流”。 (这是一种称为依赖注入的技术。)
    • 生产代码中,您的类将使用普通的“控制台”作为输入流创建。
    • 测试代码中,该类将使用模拟输入流构建,该输入流将提供由测试控制的值。
    • 通过这种方式,您的测试可以自动化,并在输入方面得到很好的控制;因此预期产出。

    Bare Bones示例代码

    [TestCase] 
    public void test() 
    { 
      <use appropriate type here> MockInputStream = new ...;
      ClassToTest testClass = new ClassToTest(MockInputStream);
    
      int Actual = 0;
      MockInputStream.PutNextInput("4");
      ClassToTest.MethodToTest(out Actual);
    
      Assert.AreEqual(4, Actual, "MockInputStream placed 4 as the next value to read");
    }