Mocking the Console

I’ve posted an update to the Microsoft.Activities.Simulation library.  Today at the team meeting I showed the library to the Windows Workflow team and Ed Pinto said “That is cool!” so I must be doing something right.

Today’s update is a better TestConsole.  This time I’ve had the TestConsole redirect the Console output stream by calling Console.SetOut.  Now the stream will go into a StringWriter backed by a StringBuilder as the buffer.

    1: StringBuilder _buffer;
    2:  
    3: public TestConsole()
    4: {
    5:     StringWriter outWriter = new StringWriter(_buffer);
    6:     Console.SetOut(outWriter);
    7: }

This way anything that writes to the console will now be captured and therefore it will become testable.

When I want to verify that something was written to the console there are two ways I can do it.  I can access the StringBuilder by calling TestConsole.Buffer.ToString() and then look for something in the string.

Or if I prefer a line oriented approach I can do something like this test.

    1: Assert.AreEqual("Scope 1 Number is 1", results.Console.Lines[0]);

Here I have a SimulationResults type with a TestConsole member named Console.  I can access a string[] named Lines that will return each line from the TestConsole buffer by calling Regex.Split

    1: public string[] Lines
    2: {
    3:     get
    4:     {
    5:         // Split it only if we need to
    6:         if (Buffer.Length != _lastBufferSplit)
    7:         {
    8:             _lastBufferSplit = Buffer.Length;
    9:             _lines = Regex.Split(Buffer.ToString(), Environment.NewLine);
   10:         }
   11:  
   12:         return _lines;
   13:     }
   14: }

Since splitting the buffer is a little work, I only split it if the length of the buffer has changed since the last time I split it.  One side effect of using Regex.Split is that you always get an empty last line.  Since the CancellationScope Activity Sample also uses this library I put the library in place and found that I had to update all the unit tests that relied on a line count.  If they asserted the count should be 2 I had to change it to 3. 

I’ m not enough of a Regex guru to know how to work around this.  For now I think it is ok to just say that you will always get one empty line at the end of the array and that is just the way it is.

If you are interested in the Microsoft.Activities.Simulation library, let me know by posting some discussion threads