I have a service which uses Microsoft.Net.Http
to retrieve some Json
data. Great!
Of course, I don't want my unit test hitting the actual server (otherwise, that's an integration test).
Here's my service ctor (which uses dependency injection...)
public Foo(string name, HttpClient httpClient = null)
{
...
}
I'm not sure how I can mock this with ... say .. Moq
or FakeItEasy
.
I want to make sure that when my service calls GetAsync
or PostAsync
.. then i can fake those calls.
Any suggestions how I can do that?
I'm -hoping- i don't need to make my own Wrapper .. cause that's crap :( Microsoft can't have made an oversight with this, right?
(yes, it's easy to make wrappers .. i've done them before ... but it's the point!)
You can replace the core HttpMessageHandler with a fake one. Something that looks like this...
public class FakeResponseHandler : DelegatingHandler
{
private readonly Dictionary<Uri, HttpResponseMessage> _FakeResponses = new Dictionary<Uri, HttpResponseMessage>();
public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage)
{
_FakeResponses.Add(uri,responseMessage);
}
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (_FakeResponses.ContainsKey(request.RequestUri))
{
return _FakeResponses[request.RequestUri];
}
else
{
return new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request};
}
}
}
and then you can create a client that will use the fake handler.
var fakeResponseHandler = new FakeResponseHandler();
fakeResponseHandler.AddFakeResponse(new Uri("http://example.org/test"), new HttpResponseMessage(HttpStatusCode.OK));
var httpClient = new HttpClient(fakeResponseHandler);
var response1 = await httpClient.GetAsync("http://example.org/notthere");
var response2 = await httpClient.GetAsync("http://example.org/test");
Assert.Equal(response1.StatusCode,HttpStatusCode.NotFound);
Assert.Equal(response2.StatusCode, HttpStatusCode.OK);