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.