Ich habe einen Dienst, der Microsoft.Net.Http
, um einige Json
Daten abzurufen. Groß!
Natürlich möchte ich nicht, dass mein Komponententest den tatsächlichen Server trifft (ansonsten ist das ein Integrationstest).
Hier ist mein Dienst ctor (der Abhängigkeitsinjektion verwendet ...)
public Foo(string name, HttpClient httpClient = null)
{
...
}
Ich bin nicht sicher, wie ich das verspotten kann mit ... sagen wir .. Moq
oder FakeItEasy
.
Ich möchte sicherstellen, dass ich diese Anrufe vortäuschen kann, wenn mein Dienst GetAsync
oder PostAsync
anruft.
Irgendwelche Vorschläge, wie ich das machen kann?
Ich muss nicht meinen eigenen Wrapper machen, weil das Mist ist :( Microsoft kann damit kein Versehen gemacht haben, oder?
(Ja, es ist einfach, Wrapper zu machen. Ich habe sie schon einmal gemacht. Aber es ist der Punkt!)
Sie können den zentralen HttpMessageHandler durch einen gefälschten ersetzen. Etwas, das so aussieht ...
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};
}
}
}
und dann können Sie einen Client erstellen, der den Fake-Handler verwendet.
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);
Ich weiß, dass dies eine alte Frage ist, aber ich bin bei einer Suche zu diesem Thema darauf gestoßen und habe eine sehr gute Lösung gefunden, um das Testen von HttpClient
zu vereinfachen.
Es ist über Nuget erhältlich:
https://github.com/richardszalay/mockhttp
PM> Install-Package RichardSzalay.MockHttp
Hier ist ein kurzer Blick auf die Verwendung:
var mockHttp = new MockHttpMessageHandler();
// Setup a respond for the user api (including a wildcard in the URL)
mockHttp.When("http://localost/api/user/*")
.Respond("application/json", "{'name' : 'Test McGee'}"); // Respond with JSON
// Inject the handler or client into your application code
var client = new HttpClient(mockHttp);
var response = await client.GetAsync("http://localost/api/user/1234");
// or without await: var response = client.GetAsync("http://localost/api/user/1234").Result;
var json = await response.Content.ReadAsStringAsync();
// No network connection required
Console.Write(json); // {'name' : 'Test McGee'}
Weitere Infos auf der Github-Projektseite. Hoffe das kann nützlich sein.
Ich würde nur eine kleine Änderung an der Antwort von @ Darrel Miller vornehmen, die Task.FromResult verwendet, um die Warnung zu vermeiden über eine asynchrone Methode, die einen wait-Operator erwartet.
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 override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (_FakeResponses.ContainsKey(request.RequestUri))
{
return Task.FromResult(_FakeResponses[request.RequestUri]);
}
else
{
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request });
}
}
}
Sie können sich Microsoft Fakes ansehen, insbesondere den Abschnitt Shims
-. Mit ihnen können Sie das Verhalten Ihres HttpClient selbst ändern. Voraussetzung ist, dass Sie VS Premium oder Ultimate verwenden.