4

I want to unit test the code below. I've been working with MSTest and I tried to learn Microsoft Moles and RhinoMocks. But I couldn't make neither of them help me. I know I can change the code drastically to use interfaces that make it more testable, but it would require me to code interfaces and implementations that encapsulate TcpClient, NetworkStream, StreamWriter and StreamReader.

I've already written integration test for this and I guess that someone proficient with moles can do unit tests for this quite easily without changing the code.

using (TcpClient tcpClient = new TcpClient(hostName, port))
using (NetworkStream stream = tcpClient.GetStream())
using (StreamWriter writer = new StreamWriter(stream))
using (StreamReader reader = new StreamReader(stream))
{
    writer.AutoFlush = true;
    writer.Write(message);
    return reader.ReadLine();
}
Jader Dias
  • 88,211
  • 155
  • 421
  • 625
  • 3
    Some things just aren't worth trying to "unit test". If you mocked out the pieces this method uses, you'd essentially be checking a property setter, a method call to `writer` and a method call to `reader`. Not a lot of behavior here, and not terribly interesting to test. Now testing classes that *use* this method would be interesting, so I'd totally make this class implement an interface, and test components that call into it. – Merlyn Morgan-Graham Dec 16 '11 at 12:33

1 Answers1

11

Keep it simple.

Abstract away the network layer. I usually use an interface called something like INetworkChannel that looks something like this:

public interface INetworkChannel : IDisposable
{
    void Connect(IPEndPoint remoteEndPoint);
    void Send(byte[] buffer, int offset, int count);

    public event EventHandler Disconnected;
    public event EventHandler<ReceivedEventArgs> Received;
}

It makes it easy to test everything and you could create SecureNetworkChannel class which uses SslStream or FastNetworkChannel which uses the new Async methods.

The details like what stream is used or if you use TcpClient or Socket should not matter to the rest of the application.

Edit

Testing the INetworkingChannel implementation is easy too since you now got a class with a very clear responsibility. I do create a connection to my implementations to test them. Let the TcpListener listen on port 0 to let the OS assign a free port.

I just make sure that it handle sends and receives properly and that it do proper clean up when a connection is closed/broken.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • +1; If I were to mock things like this out, I'd definitely want a simplified interface to the multitude of involved classes. Basically a Facade pattern (as you've done here). I like the design of this interface because there would be very few guts to implement, and pretty much no app-custom logic behind it. The only concern I have is that this isn't `IDisposible`. Should it be? – Merlyn Morgan-Graham Dec 16 '11 at 12:40
  • @MerlynMorgan-Graham: You are correct. Sockets should always be disposed, especially in servers. And a `Close` method isn't really needed since `Socket` objects cannot be reused. – jgauffin Dec 16 '11 at 12:48
  • Right, very nice simplification! – sll Dec 16 '11 at 13:12