tags:

views:

291

answers:

4

I am a newbie to unit testing. How do I check the for console output? I have

namespace XXShapes
{
    public abstract class XXShape
    {
        public virtual void DrawXXShape()
        {
            Console.WriteLine("The XXShape was drawn.");

        }
    }

public class XXCircle : XXShape
{
    public override void DrawXXShape()
    {
        Console.WriteLine("The XXCircle was drawn.");
    }
}

}

namespace XXShapes.Test
{
    [TestFixture]
    public class XXShapeTest
    {
        [Test]
        public void MyFirstTest()
        {
            XXShape s = new XXCircle();
            string expected = "The XXCircle was drawn.";
            s.DrawXXShape();
            string actual = Console.ReadLine();
            Assert.AreEqual(expected, actual);
        }
    }


}

How should I correctly be testing this? Thanks for any pointers. Cheers, ~ck

A: 

That's not at all what you'd do.

In your test you will typically check for the state of the object, with something like:

Assert.IsTrue(foo.Field, Equals, "hello")

Depending on how your chosen framework works. So you'll need to change your approach, in general, to conform to this model.

Noon Silk
+3  A: 

You don't need to test 'Console.WriteLine' routine because you have to assume it works - it is not your code, so why do you want to test it. You need to test whether you produce correct string that is passed to 'Console.WriteLine'

In other words, instead of:

public override void DrawXXShape()
{
    Console.WriteLine("The XXCircle was drawn.");
}

you could do:

public override void DrawXXShape()
{
    Console.WriteLine(produceXxCircle());
}

public string produceXxCircle()
{
    return "The XXCircle was drawn.";
}

and then in the test case:

Assert.AreEqual(produceXxCircle(), "The XXCircle was drawn.");

Hope it helps. Regads Simon

Simon
That Assert is just testing the produceXxCircle() method, not that the draw method was called.
Steve Gilham
Indeed, but what do you want to test? If Console.WriteLine is correctly outputting strings to console? You should not test this, since Console.WriteLine is not your code. It's part of the framework
Simon
Yeah, the original code as given is trying to perform a fairly empty test -- calling `s.DrawXXShape();` and then checking that the `DrawXXShape` method has been called. But at least it's making a start at testing.
Steve Gilham
+6  A: 

The literal answer would be that you would use Console.SetOut before calling the class under test to direct stdout into a memoryStream or similar, whose contents you can later inspect.

The better answer would be to use a mocking framework, like Rhino Mocks to create a concrete instance of your abstract class, with an expectation set that the DrawXXShape method would be called.

Steve Gilham
A: 

I'm assuming that some other tests test for the drawing capabilities - If you now want to test that your classes write something in particular to the console, then you should abstract the idea of writing to the console.

Create an interface with a WriteLine() method in it and inject instances that implement this interface into XXShapes. Your tests can inject mocks or stubs which can capture the strings that are written and test their contents in the tests.

quamrana