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

If I have a function that takes an out parameter and accepts an input form console -

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

How can I accept input using Console.Readline () during a NUnit test? How can I use NUnit to test this method?

I tried using this code for my NUnit test case -

 [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 that accepts an out parameter and also accepts user input from the console?

+7
c # nunit console-application
source share
2 answers

You can use the SetIn System.Console method to set the input source:

 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 check for 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' 
+3
source share

There are a few slightly different issues here.

  • You want to test a method that returns a value in the out parameter. This is actually quite trivial and hardly different from a method that returns its value as a normal function.
  • You want to test a method that reads input from the console. This is a little more complicated and fits a bit into the design of the object you are trying to test. The problem is that the "Console" is a global object, and this immediately makes testing difficult.

The crazy thing to note is that you want to test a method that accepts input from the console. That is, this implies user interaction. This is hardly a way to "automate testing", what do you think?

In response to # 2, I suggest you take a look at some of the Misko Hevery articles and videos on writing testable code.

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

For a brief description of your problem:

  • MethodToTest currently wants console input.
  • The class that contains MethodToTest must take an "input stream" in its constructor. (This is a method called dependency injection.)
  • In production code, your class will be created with a normal "Console" as input.
  • In the test code, the class will be built with a Mock input, which will pass values ​​controlled by the test.
  • Thus, your test can be automated and well controlled in terms of input; and therefore the expected results.

Bare Bones Code Example

 [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"); } 
+2
source share

All Articles