Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I would like to unit test my web requests, so on top of my head I came up with the solution below.

Since it seems to be working fine, I'm posting it on this site. Though it doesn't feel very dynamic, I would like your input. For example, this solution can't simulate response headers, which I'm also interested in mocking:

public interface IWebRequest
{
    Task<string> DownloadString();
}

public class RealWebRequest : IWebRequest
{
    private readonly string url;

    public RealWebRequest(string url)
    {
        this.url = url;
    }

    public Task<string> DownloadString()
    {
        using (WebClient client = new WebClient())
        {
            return client.DownloadStringTaskAsync(new Uri(url));
        }
    }
}

public class FakeWebRequest : IWebRequest
{
    private readonly string fakeReponse;

    public FakeWebRequest(string fakeReponse)
    {
        this.fakeReponse = fakeReponse;
    }

    public Task<string> DownloadString()
    {
        return Task.Factory.StartNew(() => fakeReponse);
    }
}

public class TestClass
{
    private readonly IWebRequest request;

    public TestClass(IWebRequest request)
    {
        this.request = request;
    }

    public async Task<string> DoStuff()
    {
        return await request.DownloadString();
    }
}

"Real" usage example:

IWebRequest realRequest = new RealWebRequest("http://www.test.com");
TestClass test = new TestClass(realRequest);
string realResult = await test.DoStuff();

Unit test usage example:

IWebRequest fakeRequest = new FakeWebRequest("fake response string");
TestClass test = new TestClass(fakeRequest);
string fakeResponse = await test.DoStuff();
share|improve this question
1  
Welcome to CodeReview. You should feel right home here, I hope you get some fine answers. –  Legato Mar 29 at 15:46

1 Answer 1

up vote 1 down vote accepted

I really rather think you have the right idea with the interface and your real class. I do heartily endorse your use of readonly which doesn't get a lot of exposure. However, there are many good mocking frameworks out there that you don't need to write your own fake class to unit test with. For instance, we use Moq where I work and your unit test example would look like this:

Mock<IWebRequest> fakeRequest = new Mock<IWebRequest>();

fakeRequest
    .Setup(request => request.DownloadString(It.IsAny<string>())
    .Returns("fake response string");

TestClass test = new TestClass(fakeRequest.Object);
string fakeResponse = await test.DoStuff();
share|improve this answer
1  
I was under the impression that httprequests were hard to mock using Moq. You have proven me wrong :) Thanks! –  filur Mar 30 at 15:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.