Unit Test and mock HTTPClient with HttpMessageHandler

Unit Test and mock HTTPClient with HttpMessageHandler

In this article, we will see how to Unit Test and mock HTTPClient with HttpMessageHandler using .NET Framework and .NET Core Framework.

Today in this article, we will cover below aspects,

If using in .NET Core applications it’s recommended to use HTTPClientFactory to create HTTPClient request objects.

You are using HTTPClient wrongly

HTTPClient is the most used and useful class both in .NET and .NET Core ecosystem used for calling various services like RESTFul and WebServices.

Over the years it was found that HTTPClient request objects are used in the wrong way. I have talked about the differences between HTTPClient Vs HTTPClientfactory in detail.

If using the .NET Framework or non-host apps you can use a static instance of HTTPClient. For Host Application Ex. ASP.NET Core-based apps its recommended to use HTTPClientfactory

Getting started

Below is the sample code API created we shall be unit testing and mocking.

The below code demonstrates how to mock basic HTTPClient usage which we shall be unit testing and mocking using XUnit and Moq.

    [Route("api/[controller]")]
    [ApiController]
    public class PayController : ControllerBase
    {

        private static HttpClient _client ;

        public PayController(HttpClient client)
        {
            _client = client;
        }

        public async Task<IActionResult> GetAccountAsyn()
        {
            var uri = new Uri("http://localhost:12121/account");

           var response = await _client.GetAsync(uri);

            if (response.IsSuccessStatusCode)
            {
                return Ok(response.Content.ReadAsStringAsync());
            }
            else
            {
                return StatusCode(500, "Server error");
            }

        }
    }

Mock HTTPClient object

Mocking the HTTPClient object is all about mocking HttpMessageHandler delegates.

Mocking HttpMessageHandler will also ensure the client calling actual endpoints are faked by intercepting it.

Mock HttpMessageHandler as below,

        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
        mockHttpMessageHandler.Protected()
            .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent("{'name':thecodebuzz,'city':'USA'}"),
            });

Create an HTTPClient object using above mocked HttpMessageHandler

   var client = new HttpClient(mockHttpMessageHandler.Object)
            {
                BaseAddress = new Uri("http://test.com/")
            };

The above base address is just a mock URL and it won’t impact the test cases anyway.

Here below is the complete method,

Mock and Unit Test HTTPClient with MessageHandler

Other references:

That’s all! Happy coding!

Does this help you fix your issue?

Do you have any better solutions or suggestions? Please sound off your comments below.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



Leave a Reply

Your email address will not be published. Required fields are marked *