Close Menu
Código Simples .NETCódigo Simples .NET
    Facebook X (Twitter) Instagram
    Trending
    • Clean Code (2ª edição): o que mudou e o que continua valendo
    • Sunk Cost em Arquitetura de Software: como evitar que meses de investimento virem uma armadilha
    • Guia Profissional de Prompting – Domando um ChatGPT Preguiçoso: Como Obter Respostas Completas, Profundas e Confiáveis
    • A Anatomia de um Prompt: Como Falar com a IA Como um Profissional de Tecnologia
    • Conheça os tipos de registros DNS: o guia completo sobre A, AAAA, NS, CNAME, MX, PTR, SOA, TXT, SRV, SPF e muito mais
    • Cache além do básico: por que LRU e TTL precisam andar juntos
    • Quando usar arquitetura modular — e quando não usar
    • Mais de 200 livros de programação gratuitos em português
    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
    • Clean Code (2ª edição): o que mudou e o que continua valendo
    • Sunk Cost em Arquitetura de Software: como evitar que meses de investimento virem uma armadilha
    • Guia Profissional de Prompting – Domando um ChatGPT Preguiçoso: Como Obter Respostas Completas, Profundas e Confiáveis
    • A Anatomia de um Prompt: Como Falar com a IA Como um Profissional de Tecnologia
    • Conheça os tipos de registros DNS: o guia completo sobre A, AAAA, NS, CNAME, MX, PTR, SOA, TXT, SRV, SPF e muito mais
    Categorias
    • Arquitetura (30)
      • Microsserviços (3)
      • Testes (2)
    • Asp.net (120)
      • C# (89)
      • Mvc (13)
    • Banco de dados (93)
      • NoSql (60)
      • Sql (38)
    • Boas práticas (34)
      • Gestão & Produtividade (4)
      • Metodologias Ágeis (6)
    • Cursos (53)
    • Dicas (108)
    • Front-End (92)
    • IA (6)
    • 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

    Código Simples no Facebook
    Código Simples no Facebook
    • Popular
    • Recente

    1000 livros gratuitos sobre programação!

    12 de fevereiro de 2016

    Google lança versão “invisível” do reCAPTCHA!

    10 de março de 2017

    Mini curso de HTML5 oferecido pela Microsoft

    30 de janeiro de 2014

    O que significa ( !important ) na declaração do CSS ?

    5 de fevereiro de 2014

    Programa para supercompactar arquivos. KGB Archiver.

    6 de fevereiro de 2014

    Clean Code (2ª edição): o que mudou e o que continua valendo

    12 de fevereiro de 2026

    Sunk Cost em Arquitetura de Software: como evitar que meses de investimento virem uma armadilha

    4 de fevereiro de 2026

    Guia Profissional de Prompting – Domando um ChatGPT Preguiçoso: Como Obter Respostas Completas, Profundas e Confiáveis

    30 de outubro de 2025

    A Anatomia de um Prompt: Como Falar com a IA Como um Profissional de Tecnologia

    30 de outubro de 2025

    Conheça os tipos de registros DNS: o guia completo sobre A, AAAA, NS, CNAME, MX, PTR, SOA, TXT, SRV, SPF e muito mais

    8 de outubro de 2025
    Nosso Feed
    • RSS - Posts
    Fique por dentro

    Digite seu endereço de email para assinar este blog e receber notificações de novas publicações por email.

    Facebook X (Twitter) Instagram LinkedIn

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

    Vá para versão mobile