TDD: Mocking System.Net.WebClient

Writing unit-test for the class that uses System.Net.WebClient, I have found out that there is no possibility to mock System.Net.WebClient using dynamic mock object frameworks (like RhinoMocks and Moq) because its methods are not virtual.

The solution is to introduce web client interface and abstract factory interface to create such web clients.

interface IWebClient : IDisposable
{
    // Required methods (subset of `System.Net.WebClient` methods).
    byte[] DownloadData(Uri address);
    byte[] UploadData(Uri address, byte[] data);
}

interface IWebClientFactory
{
    IWebClient Create();
}

The default implementations for System.Net.WebClient are straight-forward:

/// <summary>
/// System web client.
/// </summary>
public class SystemWebClient : WebClient, IWebClient
{

}

/// <summary>
/// System web client factory.
/// </summary>
public class SystemWebClientFactory : IWebClientFactory
{
    #region IWebClientFactory implementation

    public IWebClient Create()
    {
        return new SystemWebClient();
    }

    #endregion
}

Now IWebClientFactory interface can be injected as a dependency (constructor injection) and the dependent classes can be tested.

Enjoy!

One thought on “TDD: Mocking System.Net.WebClient

  1. UbuntuDude

    Hi Sergey, thank you for this interesting post. I wrote a program where I need a WebClilent but I can’t figure out how to mock it to test the dependent classes. The dependent class I wrote is as follows:

    // Create a new Stream from a URL source.
    public class UriToStream : IStream
    {
        private IWebClientFactory webClientFactory;
        private String uri;
    
        public UriToStream(IWebClientFactory w, String u)
        {
            webClientFactory = w;
            uri = u;
        }
    
        public Stream GetStream()
        {
            using (var client = webClientFactory.Create())
            {
                Stream stream = client.OpenRead(uri);
                return stream;
            }
        }
    }
    

    The above class provides a method that returns a stream from a text file located at a specified URI. I can’t figure out how to mock the webpage and I am wondering does the above class have a dependency on the String uri? Can you please advise?

    Reply

Leave a Reply (Markdown is enabled)

Your email address will not be published. Required fields are marked *