简体   繁体   English

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

[英]How can I use NUnit to test a method with out or ref parameters?

If I have a function which accepts an out parameter and accepts an input form console - 如果我有一个接受out参数并接受输入表单控制台的函数 -

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

How can I accept an input using Console.Readline() during NUnit test? 在NUnit测试期间如何使用Console.Readline()接受输入? How can I use NUnit to test this method? 如何使用NUnit测试此方法?

I tried using this code for my NUnit test case - 我尝试将此代码用于我的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");    
}

how can I test a method which accepts an out parameter and also accepts an user input from Console? 如何测试接受out参数的方法并接受来自Console的用户输入?

You can use the SetIn method of System.Console to set the the input source: 您可以使用System.ConsoleSetIn方法来设置输入源:

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

EDIT: To test multiple values, just separate each input with a new line: 编辑:要测试多个值,只需用新行分隔每个输入:

string[] lines = new[] { "line1", "line2" };
StringReader input = new StringReader(String.Join(Environment.NewLine, lines));
Console.SetIn(input);

string input1 = Console.ReadLine();    //will return 'line1'
string input2 = Console.ReadLine();    //will return 'line2'

There are 2 slightly different issues combined here. 这里有两个略有不同的问题。

  1. You want to test a method that returns a value in an out parameter. 您想测试一个在out参数中返回值的方法。 This is actually quite trivial and is hardly different from a method that returns its value as a normal function. 这实际上非常简单,并且与将其值作为正常函数返回的方法几乎没有什么不同。
  2. You want to test a method that reads input form the console. 您想测试从控制台读取输入的方法。 This one is quite a bit trickier, and goes a little into the design of the object you're trying to test. 这一点相当棘手,并且稍微考虑了您要测试的对象的设计。 The problem is that the "Console" is a global object, and that immediately makes it more difficult to test. 问题是“控制台”是一个全局对象,这会立即使测试更加困难。

The craziest thing to note is that you want to test a method that takes input from the console. 最值得注意的是,您要测试从控制台获取输入的方法。 Ie this implies user interaction. 即这意味着用户交互。 This is hardly the way to go about "automated testing" don't you think? 这不是“自动化测试”的方式你不觉得吗?

In answer to #2, I suggest you look at some of Misko Hevery's articles and videos on writing testable code. 在回答#2时,我建议你看看Misko Hevery的一些关于编写可测试代码的文章和视频。

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

For a brief summary specfic to your problem: 有关您的问题的简要摘要:

  • MethodToTest currently wants input from the console. MethodToTest当前需要来自控制台的输入。
  • The class that holds MethodToTest should take an "input stream" in its constructor. 持有MethodToTest的类应该在其构造函数中使用“输入流”。 (This is a technique called dependency injection.) (这是一种称为依赖注入的技术。)
  • In production code , your class will be created with the normal "Console" as its input stream. 生产代码中 ,您的类将使用普通的“Console”作为其输入流创建。
  • In test code , the class will be constructed with a Mock input stream that will feed values controlled by the test. 测试代码中 ,将使用Mock输入流构造类,该输入流将提供由测试控制的值。
  • In this way your test can be automated, and well controlled in terms of inputs; 通过这种方式,您的测试可以自动化,并在输入方面得到很好的控制; and therefore expected outputs. 因此预期产出。

Bare Bones Sample Code 裸骨样本代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM