Comment passer un HttpClient simulé dans un test .NET?

J’ai un service qui utilise Microsoft.Net.Http pour récupérer des données Json . Génial!

Bien sûr, je ne veux pas que mon test d’unité frappe le serveur réel (sinon, c’est un test d’intégration).

Voici mon service ctor (qui utilise l’dependency injections …)

 public Foo(ssortingng name, HttpClient httpClient = null) { ... } 

Je ne suis pas sûr de savoir comment je peux me moquer de cela, disons … Moq ou FakeItEasy .

Je veux m’assurer que lorsque mon service appelle GetAsync ou PostAsync .. alors je peux PostAsync ces appels.

Des suggestions sur comment je peux le faire?

Je suis en train de faire mes achats. Je n’ai pas besoin de faire mon propre Wrapper. Parce que c’est de la merde: (Microsoft ne peut pas avoir fait ça, n’est-ce pas?)

(oui, c’est facile de faire des wrappers .. je les ai fait avant … mais c’est le point!)

Vous pouvez remplacer le kernel HttpMessageHandler par un faux. Quelque chose qui ressemble à ça …

 public class FakeResponseHandler : DelegatingHandler { private readonly Dictionary _FakeResponses = new Dictionary(); public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage) { _FakeResponses.Add(uri,responseMessage); } protected async override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { if (_FakeResponses.ContainsKey(request.RequestUri)) { return _FakeResponses[request.RequestUri]; } else { return new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request}; } } } 

et puis vous pouvez créer un client qui utilisera le faux gestionnaire.

 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); 

Je sais que c’est une vieille question mais je l’ai trébuché lors d’une recherche sur ce sujet et j’ai trouvé une très bonne solution pour faciliter le test de HttpClient .

Il est disponible via nuget:

https://github.com/richardszalay/mockhttp

 PM> Install-Package RichardSzalay.MockHttp 

Voici un aperçu de l’utilisation:

 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.ReadAsSsortingngAsync(); // No network connection required Console.Write(json); // {'name' : 'Test McGee'} 

Plus d’infos sur la page du projet github. J’espère que cela peut être utile.

Je voudrais juste apporter une petite modification à la réponse de @Darrel Miller , qui utilise Task.FromResult pour éviter l’avertissement concernant une méthode asynchrone qui attend un opérateur d’attente.

 public class FakeResponseHandler : DelegatingHandler { private readonly Dictionary _FakeResponses = new Dictionary(); public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage) { _FakeResponses.Add(uri, responseMessage); } protected override Task 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 }); } } } 

Vous pourriez jeter un oeil à Microsoft Fakes , en particulier à la section Shims . Avec eux, vous pouvez modifier les comportements de votre HttpClient lui-même. La condition préalable est que vous utilisiez VS Premium ou Ultimate.