0

I have a function whose specification calls for it to write to stdout. When I test, stdout is MIA and I can't find it. I need to catch it so I can assert expected responses. The method will be called by a command pipeline.

In addition, I will be writing some pipeline functions: ==stdin==> method ==stdout==>. That means my unit tests need to push test data into stdin.

I am planning the test scenario before writing the methods and not finding a lot of recent information. I am hoping that MSTest might have some helper methods for this. If not, I could use some guidance regarding how I might go about writing my own.

BigTFromAZ
  • 684
  • 7
  • 22
  • make the function itself just consume generic streams - then you can test it - and write a wrapping function that pipes STDIO into this function. – Franz Gleichmann Jun 02 '20 at 18:33
  • Dotnet also provides the ability to set the input and output of Console to any TextWriter/TextReader. See [Console.SetOut](https://learn.microsoft.com/en-us/dotnet/api/system.console.setout?view=netcore-3.1) and [Console.SetIn](https://learn.microsoft.com/en-us/dotnet/api/system.console.setin?view=netcore-3.1) – bisen2 Jun 02 '20 at 18:39
  • Does this answer your question? [C# unit test for a method which calls Console.ReadLine()](https://stackoverflow.com/questions/3161341/c-sharp-unit-test-for-a-method-which-calls-console-readline) – Artur INTECH Feb 15 '23 at 08:46

1 Answers1

4

I would suggest passing in a TextReader and a TextWriter, maybe as optional parameters. You can then read from the reader and write to the writer. Then either the caller passes in Console.Out and Console.In, or you can do it in the method:

public void Foo(TextReader reader = null, TextWriter writer = null)
{
    reader = reader ?? Console.In;
    writer = writer ?? Console.Out;
    // Read and write
}

(Or use a parameterless overload that calls an overload with two required parameters.)

In your unit tests, use a StringReader and a StringWriter.

If you can required the caller to pass in the reader and the writer, it would allow you to avoid coupling your code tightly to the console, leading to generally cleaner code - I can imagine a whole series of methods all of which accept a reader/writer (or use fields for them) so that only the very top level code "knows" that it's dealing with the console.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194