Close Menu
Código Simples .NETCódigo Simples .NET
    Facebook X (Twitter) Instagram
    Trending
    • NewSQL em 2025: O Estado Atual, Tendências e o Futuro dos Bancos de Dados Relacionais Escaláveis
    • 12 Regras Essenciais para Reduzir a Latência de Aplicações
    • Cache Hit Ratio: Como uma Simples Métrica Pode Revolucionar sua Arquitetura
    • Como a Uber calcula o tempo estimado de chegada
    • 30 APIs Gratuitas para desenvolvedores
    • Por que escalar escrita é tão mais difícil do que escalar leitura?
    • MongoDB Analyzer para .NET: Visualize e otimize suas consultas de forma simples
    • Cardinalidade: O Conceito que Transforma o Desempenho de Bancos de Dados SQL e NoSQL
    Facebook X (Twitter) Instagram
    Código Simples .NETCódigo Simples .NET
    Código Simples .NETCódigo Simples .NET
    Home»Asp.net»C#»Mockando apis HttpClient usando XUnit no .NetCore

    Mockando apis HttpClient usando XUnit no .NetCore

    Jhonathan SoaresBy Jhonathan Soares15 de junho de 20202 Mins Read C#
    Share
    Facebook Twitter LinkedIn WhatsApp Copy Link

    Criar mocks nem sempre é uma tarefa fácil, principalmente se tratando de mocks de API’s ou chamadas diretas à repositórios que normalmente possuem alteração de estado. Neste artigo explicarei como simular o HttpClient usando o XUnit. Sim, já temos algumas poucas maneiras de mockar o httpclient, escrevendo um wrapper para o HttpClient.
    Mas há um problema em não cobrir casos de teste para a classe HttpClient, pois sabemos que não há uma interface herdada com o HttpClient. Para lidar com esse caso, introduzimos a propriedade HttpClient na interface. Usando essa propriedade de interface, podemos alcançar o que queremos com a simulação de uma chamada através de um httpclient.  

    Como eu já mencionei, o HttpClient não herda de nenhuma interface, então você terá que escrever sua própria. Alguns deles sugerem um padrão de decorator. Então, aqui estamos mockando apenas da classe wrapper e não do httpclient. Então, como podemos mockar o httpclient também? Vamos vê-lo em ação, estou usando o Visual Studio 2019, .Net Core 2.2 e XUnit.  

    Para demonstrar o mock de httpclient usando o Xunit, estou criando uma API simples com dados do (openweathermap.org) e adicionando um novo projeto de teste (XUnit).

    Vamos criar a interface IHttpClientHelper para mock do httpclient. Aqui você também pode ver a propriedade HttpClient, que é usada para armazenar o objeto HttpMessageHandler mockado. A classe de implementação para IHttpClientHelper é semelhante a seguir:


     public class HttpClientHelper : IHttpClientHelper
        {
            public HttpClient HttpClient { get; set; }
    
            public async Task<TResult> GetAsync<TResult>(string requestUri)
            {
                TResult objResult = default(TResult);
    
                using (var client = this.GetHttpClient())
                {
                    using (var response = await client.GetAsync(requestUri))
                    {
                        if (TryParse<TResult>(response, out objResult))
                        {
                            return objResult;
                        }
    
                        using (HttpContent content = response.Content)
                        {
                            throw new HttpRequestException(response.Content.ReadAsStringAsync().Result);
                        }
                    }
                }
            }
            private HttpClient GetHttpClient()
            {
                if (HttpClient == null)//While mocking we set httpclient object to bypass actual result.
                {
                    var _httpClient = new HttpClient();
                    _httpClient.DefaultRequestHeaders.Accept.Clear();
                    _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    return _httpClient;
                }
                return HttpClient;
            }
    
            private bool TryParse<TResult>(HttpResponseMessage response, out TResult t)
            {
                if (typeof(TResult).IsAssignableFrom(typeof(HttpResponseMessage)))
                {
                    t = (TResult)Convert.ChangeType(response, typeof(TResult));
                    return true;
                }
    
                if (response.IsSuccessStatusCode)
                {
                    t = response.Content.ReadAsAsync<TResult>().Result;
                    return true;
                }
    
                t = default(TResult);
                return false;
            }
        }
        


    Tudo bem, implementamos a classe wrapper para HttpClient. Agora vamos passar para o projeto Test e escrever casos de teste para o método GetAsync () acima. Vamos ver como mockar o HttpClient usando a propriedade da interface que criamos


     public class HttpClientHelperTest
        {
            protected HttpClientHelper HttpClientHelperUnderTest { get; }
            public HttpClientHelperTest()
            {
                HttpClientHelperUnderTest = new HttpClientHelper();
            }
    
            /// <summary>
            /// Weather info by city name test cases are resides.
            /// </summary>
            public class GetAsyncHttpHelper : HttpClientHelperTest
            {
                [Fact]
                public async Task When_GetAsync_Returns_Success_Result()
                {
                    //Arrange;
                    var result = new List<CityInfo>()  {
                         new CityInfo() { baseinfo="stations",timezone=-10800, name="Alfenas" }
                    };
                    var httpMessageHandler = new Mock<HttpMessageHandler>();
                    var fixture = new Fixture();
    
                    // Setup Protected method on HttpMessageHandler mock.
                    httpMessageHandler.Protected()
                        .Setup<Task<HttpResponseMessage>>(
                            "SendAsync",
                            ItExpr.IsAny<HttpRequestMessage>(),
                            ItExpr.IsAny<CancellationToken>()
                        )
                        .ReturnsAsync((HttpRequestMessage request, CancellationToken token) =>
                        {
                            HttpResponseMessage response = new HttpResponseMessage();
                            response.StatusCode = System.Net.HttpStatusCode.OK;//Setting statuscode
                            response.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(result)); // configure your response here
                            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); //Setting media type for the response
                            return response;
                        });
    
                    var httpClient = new HttpClient(httpMessageHandler.Object);
                    httpClient.BaseAddress = fixture.Create<Uri>();
    
                    HttpClientHelperUnderTest.HttpClient = httpClient; //Mocking setting Httphandler object to interface property.
    
                    //Act
                    var weatherResult = await HttpClientHelperUnderTest.GetAsync<List<CityInfo>>(string.Empty);
    
                    // Assert
                    Assert.NotNull(weatherResult);
                }
            }
        }
        

    Aqui você pode ver o mock do HttpMessageHandler e atribuindo-o a um construtor HttpClient. O método SendAsync () é a implementação padrão para todas as ações HttpClient.

    Mocking Httpclient Using XUnit In .Net Core

    Vamos verificar rapidamente os resultados do caso de teste:

    O Swagger da nossa aplicação fica assim:

    Existe um método de autenticação (as credenciais estão no appsettings) para gerar um bearer token para você utilizar a API de consulta de tempo por nome de cidade.

    Código Fonte: https://github.com/jhomarolo/MockHttpClientOpenweather

    Referência https://dejanstojanovic.net/aspnet/2020/march/mocking-httpclient-in-unit-tests-with-moq-and-xunit/   

    Share. Facebook Twitter LinkedIn Telegram WhatsApp Copy Link
    Jhonathan Soares
    • Website
    • Facebook
    • X (Twitter)
    • LinkedIn

    Criador do blog Código Simples e com mais 15 anos de experiência em TI, com títulos de MVP Microsoft na área de Visual Studio Development, Neo4j Top 50 Certificate, Scrum Master e MongoDB Evangelist.

    Posts Relacionados

    O que é a Ecma e qual é sua relação com C#?

    C# Post do Leitor 29 de julho de 20247 Mins Read

    UUID vs ULID: comparação e exemplos em C#

    C# 19 de junho de 20245 Mins Read

    Entendendo o ObjectId no MongoDB

    C# NoSql 25 de maio de 20246 Mins Read
    Newsletter

    Digite seu endereço de e-mail para receber notificações de novas publicações por e-mail.

    Junte-se a 25mil outros assinantes
    Posts recentes
    • NewSQL em 2025: O Estado Atual, Tendências e o Futuro dos Bancos de Dados Relacionais Escaláveis
    • 12 Regras Essenciais para Reduzir a Latência de Aplicações
    • Cache Hit Ratio: Como uma Simples Métrica Pode Revolucionar sua Arquitetura
    • Como a Uber calcula o tempo estimado de chegada
    • 30 APIs Gratuitas para desenvolvedores
    Categorias
    • Arquitetura (14)
      • Testes (2)
    • Asp.net (120)
      • C# (89)
      • Mvc (13)
    • Banco de dados (90)
      • NoSql (58)
      • Sql (38)
    • Boas práticas (29)
      • Gestão & Produtividade (1)
      • Metodologias Ágeis (6)
    • Cursos (52)
    • Dicas (105)
    • Front-End (92)
    • IA (1)
    • Linux (6)
    • NodeJS (4)
    • Post do Leitor (9)
    • Python (5)
    • Seo (12)
    • Tecnologia (30)
      • ITIL (1)
      • Padrões de Projeto (4)
    • Testes (2)

    VEJA TAMBÉM

    Cursos
    12 de fevereiro de 20166 Mins Read

    1000 livros gratuitos sobre programação!

    Olha que dica bacana! A pagina só com livros sobre programação é mantida no GitHub…

    30 APIs Gratuitas para desenvolvedores

    Facebook X (Twitter) Instagram LinkedIn

    Type above and press Enter to search. Press Esc to cancel.

    Vá para versão mobile