Posted on October 18th, 2007

A question came up on the TDD mailing list earlier this week – how do you deal with an application that closes your memory stream before you have a chance to assert what is going on with it?

The solution the poster did was to have a byte array and have a stream on that. But you actually have a couple of choices:

Strings – If your app is writing strings (say logging messages) then you can use System.IO.StringWriter. It uses a StringBuilder as a backing store which will still be around even if your app closes the stream.

Other Streams – but if you really need to compare streams, then you have the System.IO.MemoryStream. However, you can’t see what is in it once it has been closed. For example:

static void Main(string[] args)
{
  using(MemoryStream stream = new MemoryStream())
  {
    WriteToStream(stream);
    stream.Position = 0;
    byte b1 = (byte)stream.ReadByte();
    Console.WriteLine(b1.ToString());
  }
}

static void WriteToStream(Stream stream)
{
  byte b = 1;
  stream.WriteByte(b);
}

outputs “1″ as expected. However, if we closed the stream in WriteToStream, we get an error:

static void WriteToStream(Stream stream)
{
  byte b = 1;
  stream.WriteByte(b);
  stream.Close();
}

As we saw above, one solution would be to use a byte array or something else that will still be around. However, another choice is to fake out the method closing the Stream by deriving a class:

class FakeCloseMemoryStream : MemoryStream
{
  public FakeCloseMemoryStream() : base() { }
  public bool closeWasCalled = false;
  public override void Close()
  {
    closeWasCalled = true;
  }
  public void ReallyClose()
  {
    base.Close();
  }
}

static void Main(string[] args)
{
  FakeCloseMemoryStream stream =
    new FakeCloseMemoryStream();
  WriteToStream(stream);
  stream.Position = 0;
  byte b1 = (byte)ReadByte();
  Console.WriteLine(b1.ToString());
  stream.ReallyClose();
}

Which gets us nicely past it. Of course, your requirements may not allow for this, but when you need something to stand in, remember that subclassing can be your friend.

Leave a Reply