4

I wants unit test the Search class below that uses HttpClient,

public class Search:ISearch{
HttpClient httpClient;
  public Search(HttpClient httpClient){
   this.httpClient = httpClient;
}
   //use httClient to send request.
}

Is there a way to mock the HttpClient? I cannot find any information via Google.

Update

Is there an alternaitve to sending an Http web request that can be mocked. I have the code below:

 public class Search:ISearch{
private static readonly string url = "http://www.google.com/search";
public Result SendSearch(string query){
           string queryUrl = string.Format("{0}?q={1}", url, query);
           var webRequest = WebRequest.Create(queryUrl);
          ///...
}
1
  • Hmm, do you really want to mock a part of the framework? I don't see how this would gain you anything, but perhaps I'm just missing your point. Commented Mar 10, 2013 at 18:54

2 Answers 2

3

In .Net 4.5 framework you can do this.

public class FakeHttpMessageHandler : HttpMessageHandler
{
    private HttpResponseMessage response;

    public FakeHttpMessageHandler(HttpResponseMessage response)
    {
        this.response = response;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var responseTask =  new TaskCompletionSource<HttpResponseMessage>();
        responseTask.SetResult(response);

        return responseTask.Task;
    }
}


[TestMethod]
public void TestGetContents()
{
    var responseMessage = new HttpResponseMessage();
    var messageHandler = new FakeHttpMessageHandler(responseMessage);
    var client = new HttpClient(messageHandler);
    var sut = new Search(client);

    sut.SendSearch("urQuery");

    // Asserts
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can't mock it with a mocking framework like Rhino-Mocks, because in order to do that you need either an interface or virtual methods on the HttpClient class. A mocking framework will create a mock for you, that either implements the methods defined on the interface or overrides the methods of your virtual class.

So either you wrap the HttpClient class and let it implement an interface, or, don't mock it.

If you'd change your code to something like this:

public class Search:ISearch
{
    private static readonly string url = "http://www.google.com/search";
    private readonly IWebRequestCreator _generator;

    public Search(IWebRequestCreator generator)
    {
        _generator = generator;
    }

    public Result SendSearch(string query)
    {
        var queryUrl = string.Format("{0}?q={1}", url, query);
        var webRequest = _generator.Create(queryUrl);
        // ...
    }
}

If you create a class that implements the IWebRequestCreator then you'd be able to mock the functionality. The implementing class would just call WebRequest.Create(queryUrl);

2 Comments

Yeah, wrap it :). Not sure how your caller of Search is defined, but maybe you can steal some ideas from this post: stackoverflow.com/questions/9823039/…
@Pingpong made an update according to your update in your question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.