Posterior a investigar en varios repositorios y sitios webs de internet al final dimos con la respuesta que te enseñaremos a continuación.
Solución:
La extensibilidad de HttpClient radica en el HttpMessageHandler
pasado al constructor. Su intención es permitir implementaciones específicas de la plataforma, pero también puede burlarse de ella. No es necesario crear un contenedor de decorador para HttpClient.
Si prefiere un DSL a usar Moq, tengo una biblioteca en GitHub / Nuget que facilita un poco las cosas: https://github.com/richardszalay/mockhttp
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://localhost/api/user/1234");
// or without async: var response = client.GetAsync("http://localhost/api/user/1234").Result;
var json = await response.Content.ReadAsStringAsync();
// No network connection required
Console.Write(json); // 'name' : 'Test McGee'
Estoy de acuerdo con algunas de las otras respuestas en que el mejor enfoque es simular HttpMessageHandler en lugar de envolver HttpClient. Esta respuesta es única en el sentido de que todavía inyecta HttpClient, lo que le permite ser un singleton o administrado con inyección de dependencia.
HttpClient está diseñado para instanciarse una vez y reutilizarse durante la vida útil de una aplicación.
(Fuente).
Burlarse de HttpMessageHandler puede ser un poco complicado porque SendAsync está protegido. Aquí hay un ejemplo completo, usando xunit y Moq.
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using Moq.Protected;
using Xunit;
// Use nuget to install xunit and Moq
namespace MockHttpClient
class Program
static void Main(string[] args)
var analyzer = new SiteAnalyzer(Client);
var size = analyzer.GetContentSize("http://microsoft.com").Result;
Console.WriteLine($"Size: size");
private static readonly HttpClient Client = new HttpClient(); // Singleton
public class SiteAnalyzer
public SiteAnalyzer(HttpClient httpClient)
_httpClient = httpClient;
public async Task GetContentSize(string uri)
var response = await _httpClient.GetAsync( uri );
var content = await response.Content.ReadAsStringAsync();
return content.Length;
private readonly HttpClient _httpClient;
public class SiteAnalyzerTests
[Fact]
public async void GetContentSizeReturnsCorrectLength()
// Arrange
const string testContent = "test content";
var mockMessageHandler = new Mock();
mockMessageHandler.Protected()
.Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny())
.ReturnsAsync(new HttpResponseMessage
StatusCode = HttpStatusCode.OK,
Content = new StringContent(testContent)
);
var underTest = new SiteAnalyzer(new HttpClient(mockMessageHandler.Object));
// Act
var result = await underTest.GetContentSize("http://anyurl");
// Assert
Assert.Equal(testContent.Length, result);
Tu interfaz expone el concreto HttpClient
class, por lo tanto, cualquier clase que use esta interfaz está vinculada a ella, esto significa que no se puede burlar de ella.
HttpClient
no hereda de ninguna interfaz por lo que tendrás que escribir la tuya propia. Sugiero un como un decorador patrón:
public interface IHttpHandler
HttpResponseMessage Get(string url);
HttpResponseMessage Post(string url, HttpContent content);
Task GetAsync(string url);
Task PostAsync(string url, HttpContent content);
Y tu clase se verá así:
public class HttpClientHandler : IHttpHandler
private HttpClient _client = new HttpClient();
public HttpResponseMessage Get(string url)
return GetAsync(url).Result;
public HttpResponseMessage Post(string url, HttpContent content)
return PostAsync(url, content).Result;
public async Task GetAsync(string url)
return await _client.GetAsync(url);
public async Task PostAsync(string url, HttpContent content)
return await _client.PostAsync(url, content);
El punto en todo esto es que HttpClientHandler
crea su propio HttpClient
, puede, por supuesto, crear varias clases que implementen IHttpHandler
En maneras diferentes.
El problema principal con este enfoque es que está escribiendo efectivamente una clase que solo llama a métodos en otra clase, sin embargo, podría crear una clase que hereda de HttpClient
(Ver El ejemplo de Nkosi, es un enfoque mucho mejor que el mío). La vida sería mucho más fácil si HttpClient
tenía una interfaz de la que se podía burlar, pero lamentablemente no la tiene.
Este ejemplo es no el boleto dorado sin embargo. IHttpHandler
todavía se basa en HttpResponseMessage
, que pertenece a System.Net.Http
espacio de nombres, por lo tanto, si necesita otras implementaciones además de HttpClient
, tendrá que realizar algún tipo de mapeo para convertir sus respuestas en HttpResponseMessage
objetos. Esto, por supuesto, es solo un problema. si necesita utilizar varias implementaciones de IHttpHandler
pero no parece que tú lo hagas, así que no es el fin del mundo, pero es algo en lo que pensar.
De todos modos, simplemente puedes burlarte IHttpHandler
sin tener que preocuparte por el hormigón HttpClient
class ya que se ha abstraído.
Recomiendo probar el no asincrónico métodos, ya que todavía llaman a los métodos asincrónicos pero sin la molestia de tener que preocuparse por los métodos asincrónicos de prueba unitaria, consulte aquí
valoraciones y comentarios
Acuérdate de que tienes concesión de decir si te fue de ayuda.