Skip to content

Cory Foy

Organizational agility through intersecting business and technology

Menu
  • FASTER Fridays
  • Mapping Mondays
  • Player Embed
  • Search Videos
  • User Dashboard
  • User Videos
  • Video Category
  • Video Form
  • Video Tag
Menu

How to Test something that closes the stream?

Posted on October 18, 2007 by Cory Foy

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.

© 2025 Cory Foy | Powered by Superbs Personal Blog theme