Reputation: 8019
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);
///...
}
Upvotes: 4
Views: 2649
Reputation: 2245
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
}
Upvotes: 3
Reputation: 14982
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);
Upvotes: 2